2015-03-31 98 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