【问题标题】:"Invalid precision or scale value" error from SQL Server with pypyodbc for Decimal('0.00'), Decimal('0.12')来自 SQL Server 的“无效的精度或比例值”错误,pypyodbc for Decimal('0.00'), Decimal('0.12')
【发布时间】:2015-05-12 16:13:46
【问题描述】:

我正在用 python 开发一个应用程序。我正在将一些财务数据插入数据库。我有大约。 1300 个表都具有相同的架构,每个公司一个表。

我正在使用 pypyodbc 1.3.3(最新)。

我有 Decimal 作为数据类型。我使用的精度为十进制(8,2)。 在我的表中,数据类型是 DATE、DECIMAL、TINYINT 和 INT。 我在我的 python 程序的一个表中插入以下行。

['05-JAN-2015', Decimal('30.90'), Decimal('31.40'), Decimal('30.40'), Decimal('30.85'), None, Decimal('0.00'), Decimal('0.00'), None, Decimal('0.00'), Decimal('0.00'), None, Decimal('0.00'), Decimal('0.00'), None, None, Decimal('30.88'), Decimal('0.00'), Decimal('0.00'), Decimal('0.00'), Decimal('0.00'), 32024, 321, Decimal('0.00'), Decimal('0.00'), None, Decimal('0.00'), None, Decimal('0.00')]

05-JAN-2015 的数据类型为 DATE,所有None 的数据类型为 TINYINT,值32024, 321 的数据类型为 INT。 但我仍然得到 SQL 异常为

  File "C:\Python27\lib\site-packages\pypyodbc.py", line 1470, in execute
    self._BindParams(param_types)
  File "C:\Python27\lib\site-packages\pypyodbc.py", line 1433, in _BindParams
    check_success(self, ret)
  File "C:\Python27\lib\site-packages\pypyodbc.py", line 986, in check_success
    ctrl_err(SQL_HANDLE_STMT, ODBC_obj.stmt_h, ret, ODBC_obj.ansi)
  File "C:\Python27\lib\site-packages\pypyodbc.py", line 964, in ctrl_err
    raise Error(state,err_text)
Error: (u'HY104', u'[HY104] [Microsoft][SQL Server Native Client 10.0]Invalid precision or scale value')

当我尝试从 Management Studio 将相同的数据直接插入 SQL Server 时,它会成功插入。 我已经交叉检查了变量的数据类型,一切都很完美。

当我在循环中将数据插入到 ~1300 个表中时,有点像

for i in range(tables_number):
    insertion_data = calculate_values()
    insert_into_db(insertion_data)

,这会导致问题吗? 我也尝试过在循环中使用 0.1 秒的延迟。

有人知道吗?这是驱动程序中的错误吗?或者还有其他我失踪的原因吗?

更新:

调试代码后发现在脚本pypyodbc.py中,函数SQLBindParameter(<many parameters>)返回-1SQL_ERROR,参数Decimal('0.00') or Decimal(0.12) or Decimal(-0.12)表示0.*形式的小数

【问题讨论】:

    标签: python sql-server sql-server-2008 pyodbc pypyodbc


    【解决方案1】:

    这似乎是 pypyodbc 中的一个错误。此代码使用 pypyodbc 1.3.3,正如您所描述的那样失败...

    from decimal import *
    import pypyodbc
    connStr = "DSN=myDb_SQLEXPRESS;"
    cnxn = pypyodbc.connect(connStr, autocommit=True)
    crsr = cnxn.cursor()
    sql = "INSERT INTO Invoices (InvoiceAmount) VALUES (?)"
    invamt = Decimal('0.01')
    crsr.execute(sql, [invamt])
    crsr.close()
    cnxn.close()
    

    ...但是使用 pyodbc 做同样的事情没问题:

    from decimal import *
    import pyodbc
    connStr = "DSN=myDb_SQLEXPRESS;"
    cnxn = pyodbc.connect(connStr, autocommit=True)
    crsr = cnxn.cursor()
    sql = "INSERT INTO Invoices (InvoiceAmount) VALUES (?)"
    invamt = Decimal('0.01')
    crsr.execute(sql, [invamt])
    crsr.close()
    cnxn.close()
    

    此外,如果我针对 MySQL 数据库中的相同表运行 pypyodbc 版本...

    from decimal import *
    import pypyodbc
    connStr = "DSN=usbMySQL;"
    cnxn = pypyodbc.connect(connStr, autocommit=True)
    crsr = cnxn.cursor()
    sql = "INSERT INTO Invoices (InvoiceAmount) VALUES (?)"
    invamt = Decimal('0.01')
    crsr.execute(sql, [invamt])
    crsr.close()
    cnxn.close()
    

    ...插入数据库的值是0.10,而不是0.01

    【讨论】:

    • 哦.. 我花了 2 天时间尝试更改完整的数据库架构以增加十进制数字的大小,并尝试了从其他论坛获得的各种可能性。非常感谢,迁移到 pyodbc 解决了它
    猜你喜欢
    • 2015-05-15
    • 1970-01-01
    • 2011-10-13
    • 2018-05-19
    • 1970-01-01
    • 2021-11-16
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多