2015-03-31 140 views
2

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

存储过程:

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 

看来pyodbc不会看到错误时,有通过SELECT语句交织结果记录。这里有什么问题,有没有办法解决这个问题?

编辑:我使用ADO试图与pymssql和看到相同的行为

+0

那么有pymssql – 2015-03-31 22:16:21

+0

@NickBailey尝试,和相同的行为 – user3885927 2015-03-31 22:19:06

回答

1

我能够使用pypyodbc与Python 3.4.3重新您的问题,也与一个VBScript。看起来,一旦存储过程发出结果集,则ODBC会通知SP已返回某种东西,并且SP中的后续错误不会在调用过程中触发错误。

一种可能的解决方法是构造您的存储过程,以便它不会在结束之前生成任何结果集。如果T-SQL代码在执行任何创建结果集的SELECT之前遇到错误,则该错误将传回给调用者。例如,这优化了你的存储过程的版本并抛出一个错误,吡吡] 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