我在SQL Server中编写了一个存储过程,它传递了4个参数。我想检查第一个参数@table_name
,以确保它只使用白名单字符,如果没有,将尝试写入另一个数据库中的表(我有DML权限)。
如果名称好,则工作正常,但如果不好,则Python返回
TypeError:“NoneType”对象不可迭代
(这对我来说是意料之中的,因为没有这样的表),但是它没有写入它应该写入的表,并且表被卡住,直到我关闭程序。
当我使用相同的参数从SSMS运行存储过程时,它工作得很好,并成功地写入日志表。
create_str = "CREATE PROC sp_General_GetAllData (@table_name AS NVARCHAR(MAX),\
@year AS INT, @month AS INT, @pd AS INT)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql NVARCHAR(MAX) # for later uses
IF @table_name LIKE '%[^a-zA-Z0-9_]%'
BEGIN
# the 'log' table allows NULLs and the fields are used in other cases
INSERT INTO [myDB].[mySchema].[log]
VALUES (SUSER_SNAME(), NULL, NULL, NULL, NULL, NULL,
'INVALID TABLE NAME: ' + @table_name, GETDATE())
RAISERROR ('Bad table name! Contact your friendly DBA for details', 0, 0)
RETURN
END
# do some things if the @table_name is ok...
END"
cursor = sql_conn.execute(create_str)
cursor.commit()
# calling the SP from python - doesn't write to the log table which gets stuck
query = "{CALL sp_General_GetAllData (?, ?, ?, ?)}"
data = pd.read_sql(query, sql_conn, params=['just*testing', 2019, 7, 2])
# calling the SP from SSMS - works fine
EXEC sp_General_GetAllData 'just*testing', 2019, 7, 2
由于第一个参数中的“*”,因此需要向[myDB].[mySchema].[log]
插入一行,只有当我从SSMS调用SP时才会发生这种情况,而不是从python调用。为什么?
解决方案:
幸运的是,我发现问题在于当从python发送对SP的调用时,INSERT INTO子句没有提交,它只是等待提交顺序。解决方案是将auto_commit=True
添加到pyodbc.connect()
函数
3条答案
按热度按时间42fyovps1#
我也遇到了同样的问题,但是,在“pyodbc.connect()”中添加“auto_commit=True”并没有解决我的问题。我通过在insert语句后添加以下命令解决了这个问题:
hgtggwj02#
试试这个链接。也许你的问题是从你的配置mysql连接。通过使用SqlAlchemy、MySql连接器或其他连接器,默认情况下禁用自动提交。
About MySQLdb conn.autocommit(True), Mika's Answer
u5rb5r593#
我正在使用pyodbc + pandas read_sql方法,遇到了这个问题。
对我来说,解决方案是在Python脚本的末尾提交并关闭pyodbc连接。