pyodbc 不报告 sql server 错误

Posted

技术标签:

【中文标题】pyodbc 不报告 sql server 错误【英文标题】:pyodbc doesn't report sql server error 【发布时间】:2015-03-31 20:16:46 【问题描述】:

我有一个问题,pyodbc 没有捕获从存储过程返回的错误。我的实际存储过程做了很多事情,但为了演示错误,我创建了一个简单的过程和相关的 python 代码。相关代码如下:

存储过程:

CREATE PROCEDURE [dbo].[testErrors]
    -- Add the parameters for the stored procedure here

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    -- Insert statements for procedure here
    insert into Parameter(Name, Units, DataType) values (null, null, null)
END

GO

Python 代码:

import pyodbc
connectString = "DRIVER=SQL Server;SERVER=%s;DATABASE=%s;UID=%s;PWD=%s" % (r'srvr', r'mydb', r'usr', r'pwd')
cnxn = pyodbc.connect(connectString)
cnxn.autocommit = True
cursor = cnxn.cursor()
cursor.execute("exec testErrors")
cursor.close()

我得到了预期的错误:

 cursor.execute("exec testErrors")
pyodbc.IntegrityError: ('23000', "[23000] [Microsoft][ODBC SQL Server Driver][SQL Server]Cannot insert the value NULL into column 'Name', table 'Parametrics.dbo.Parameter'; column does not allow nulls. INSERT fails. (515) (SQLExecDirectW); [01000] [Microsoft][ODBC SQL Server Driver][SQL Server]The statement has been terminated. (3621)")

但是,当我修改存储过程以包含 select 语句时,错误不再返回到我的 python 代码。 Python 代码像没有发生错误一样退出。

更新的存储过程:

CREATE PROCEDURE [dbo].[testErrors]
    -- Add the parameters for the stored procedure here

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    select 108
    -- Insert statements for procedure here
    insert into Parameter(Name, Units, DataType) values (null, null, null)
END

GO

当通过 select 语句有交错的结果记录时,pyodbc 似乎没有看到错误。这里有什么问题,有没有办法克服这个问题?

编辑:我用 pymssql 试过了,看到同样的行为

【问题讨论】:

还有 pymssql @NickBailey 试过了,结果还是一样 【参考方案1】:

我能够使用 pypyodbc 使用 Python 3.4.3 以及使用 ADO 的 VBScript 重新创建您的问题。似乎一旦存储过程发出了结果集,ODBC 就会注意到 SP 已返回 something 并且 SP 中的后续错误不会触发调用过程中的错误。

一种可能的解决方法是构建您的存储过程,使其直到最后都不会产生任何结果集。如果 T-SQL 代码在执行任何创建结果集的 SELECT 之前遇到错误,则错误将被传递回调用者。例如,您的存储过程的这个调整版本确实会引发 py[py]odbc 可以捕获的错误:

CREATE PROCEDURE [dbo].[Table1sp] AS
BEGIN
    DECLARE @foo int;
    SET NOCOUNT ON;
    SELECT @foo = 108;
    INSERT INTO Table1 (textcol) VALUES (NULL);  -- error here
    SELECT @foo AS foo
END

【讨论】:

以上是关于pyodbc 不报告 sql server 错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 pyodbc 将 Python 连接到 MS SQL Server

使用 pyodbc 批量插入 SQL Server 表:找不到文件

PYODBC 截断 SQL Server FOR JSON 查询的响应

linux上的Django-pyodbc SQL Server/freetds服务器连接问题

查询大型 SQL Server 表时,pymssql/pyodbc 性能(cursor.execute)非常慢

PyOdbc 无法连接到 sql server 实例