pyodbc doesn't report sql server error

邮差的信 提交于 2019-12-11 03:32:38

问题


I have an issue where pyodbc doesn't capture errors returned from stored procedure. My actual stored proc does a lot of stuff but for the purpose of demonstrating the error I created a simple proc and associated python code. Relevant code is below:

Stored Procedure:

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 code:

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()

Error I get as expected:

 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)")

However when I modified my stored procedure to include a select statement the error no longer comes back to my python code. Python code exits as if no error has occurred.

Updated Stored Procedure:

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

It seems pyodbc doesn't see the error when there are interleaving result records through select statements. What is the issue here and is there a way to overcome this issue?

EDIT: I tried this with pymssql and see the same behavior


回答1:


I was able to recreate your issue with Python 3.4.3 using pypyodbc, and also with a VBScript using ADO. It appears that once a stored procedure has emitted a result set then ODBC notices that the SP has returned something and subsequent errors in the SP don't trigger an error in the calling procedure.

One possible workaround would be to structure your stored procedure so that it doesn't produce any result set(s) until the very end. If the T-SQL code encounters an error before executing any SELECT that creates a result set then the error gets passed back to the caller. For example, this tweaked version of your stored procedure does throw an error that py[py]odbc can catch:

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


来源:https://stackoverflow.com/questions/29377756/pyodbc-doesnt-report-sql-server-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!