"Invalid precision or scale value" 来自 SQL 服务器的错误与 pypyodbc for Decimal('0.00'), Decimal('0.12')
"Invalid precision or scale value" error from SQL Server with pypyodbc for Decimal('0.00'), Decimal('0.12')
我正在 python 中开发应用程序。我正在将一些财务数据插入数据库。我有大约。 1300 个 table 都具有相同的架构,每个公司一个 table。
我正在使用 pypyodbc 1.3.3(最新)。
我的数据类型为小数。我正在使用 as Decimal(8,2) 的精度。
在我的 table 中,数据类型是 DATE、DECIMAL、TINYINT 和 INT。
我在 python 程序的 table 之一中插入以下行。
['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 服务器时,插入成功。
我已经交叉检查了变量的数据类型,一切都很完美。
因为我在循环中将数据插入到 ~1300 tables 中,有点像
for i in range(tables_number):
insertion_data = calculate_values()
insert_into_db(insertion_data)
,这会导致问题吗?
我也试过在循环中使用0.1秒的延迟。
有人知道吗?这是驱动程序中的错误吗?还是我遗漏了任何其他原因?
更新:
调试代码后,我发现在脚本pypyodbc.py
中,函数SQLBindParameter(<many parameters>)
returns-1
对于参数[=22=是SQL_ERROR
] 表示形式为 0.*
的小数
这似乎是 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()
此外,如果我 运行 pypyodbc 版本针对 MySQL 数据库中的相同 table ...
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
。
我正在 python 中开发应用程序。我正在将一些财务数据插入数据库。我有大约。 1300 个 table 都具有相同的架构,每个公司一个 table。
我正在使用 pypyodbc 1.3.3(最新)。
我的数据类型为小数。我正在使用 as Decimal(8,2) 的精度。 在我的 table 中,数据类型是 DATE、DECIMAL、TINYINT 和 INT。 我在 python 程序的 table 之一中插入以下行。
['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 服务器时,插入成功。 我已经交叉检查了变量的数据类型,一切都很完美。
因为我在循环中将数据插入到 ~1300 tables 中,有点像
for i in range(tables_number):
insertion_data = calculate_values()
insert_into_db(insertion_data)
,这会导致问题吗? 我也试过在循环中使用0.1秒的延迟。
有人知道吗?这是驱动程序中的错误吗?还是我遗漏了任何其他原因?
更新:
调试代码后,我发现在脚本pypyodbc.py
中,函数SQLBindParameter(<many parameters>)
returns-1
对于参数[=22=是SQL_ERROR
] 表示形式为 0.*
这似乎是 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()
此外,如果我 运行 pypyodbc 版本针对 MySQL 数据库中的相同 table ...
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
。