2012-04-27 71 views
1

我有一個DataSnap方法,它在刪除之前記錄已刪除的記錄。如果刪除失敗,我將回滾該事務,以便日誌記錄也不會保留。失敗的典型原因是正在刪除的記錄正在另一個表中使用。重新生成SQL錯誤 - SQL錯誤正在丟失

我的SQL類似於此:

begin transaction 
begin try 
    insert into audit ([fields]) values ([the vlaues]) 
    delete [sometable] where [id] = [someid] 
    commit transaction 
end 
begin catch 
    rollback transaction 
end catch 

這一切正常。但是,錯誤消息被抑制,因此DataSnap服務器從不會看到它。 SQL語法錯誤總是出現錯誤消息,而其他插入/更新唯一鍵和外鍵衝突始終會返回錯誤。我不明白爲什麼這段代碼會抑制錯誤。 DataSnap代碼很簡單:

procedure TMyClass.DeleteRecord([params]); 
var 
    qry: TSQLQuery; 
begin 
    qry := TSQLQuery.Create; 
    ... 
    qry.CommandText := [sql from above]; 
    qry.ParamByName('[params]').Value := [Values]; 
    qry.ExecSQL; // <- No error is raised here 
end; 

該查詢執行得很好,因此沒有語法錯誤或綁定參數的問題。我從來沒有看到外鍵違規錯誤。當我運行在SQL Management Studio中的SQL,我總是看到錯誤......所以我試圖改變catch塊如下:

try catch 
    rollback transaction 
    raiserror(N'Test Error Message', 16, 1) 
end catch 

我還沒有看到調試DataSnap服務器時產生錯誤,所以當然,客戶端應用程序對錯誤一無所知。有沒有人有任何想法,爲什麼'raiserror'和外鍵違規錯誤(s)不在DataSnap服務器中?

僅供參考 - 我使用的是Windows Server 2008 R2上運行的Delphi XE2 Enterprise和SQL Server 2008 R2。

回答

0

該解決方案最終非常簡單。在SQL語句的開頭添加set nocount on;修復了從DataSnap隱藏錯誤的問題。我以前見過這個 - 但主要是當數據返回時。由於這使用qry.ExecSQL();,因此我也沒有想到nocount也在這裏。

這裏是我使用回滾事務後,再加註SQL錯誤代碼:

set nocount on; 
begin transaction 
begin try 
    insert into audit ([fields]) values ([the vlaues]) 
    delete [sometable] where [id] = [someid] 
    commit transaction 
end 
begin catch 
    declare @eMsg nvarchar(2048), @eSv int, @eSt int 
    select @eMsg = error_message(), @eSv = error_severity(), @eSt = error_state() 
    rollback transaction 
    raiserror(@eMsg, @eSv, @eSt) 
end catch 

現在,在客戶端應用程序重新拋出錯誤顯示爲所需。