2013-12-18 86 views
1

我發佈這更多作爲提示,因爲我自己找到答案(在同事的幫助下)。子查詢返回的值超過1個

我們公司(服務器P)的生產域中有一個SQL Server 2012系統,它將主數據庫(M)的表(T)中的記錄複製到業務域中的另一個SQL Server 2012系統服務器B,相同的數據庫和表名稱)。

我們正在業務服務器上的單獨數據庫(E)中安裝新的ERP系統。供應商要求我將來自表T的數據填充到數據庫中的同名數據表中,這些數據到達業務服務器後,包括來自連接表(J)和視圖(V)的數據。我寫了下面的觸發:

CREATE TRIGGER [dbo].[After_Insert_T] ON [dbo].[T] AFTER INSERT AS 
    BEGIN 
     SET NOCOUNT ON; -- Prevent extra result sets interfering with SELECT statements. 
     SET XACT_ABORT OFF; -- Avoid automatically rolling back current transaction 

     BEGIN TRY 
     INSERT E.dbo.T 
     SELECT inserted.C1, inserted.C2, inserted.C3, J.C5, V.C7 
     FROM inserted LEFT OUTER JOIN 
      J ON inserted.C4 = J.C1 LEFT OUTER JOIN 
      V ON inserted.C6 = V.C1 
      AND inserted.C3 BETWEEN J.C8 AND J.C9; 
     END TRY 

     BEGIN CATCH 
     DECLARE @ErrorMessage NVARCHAR(4000); 
     DECLARE @ErrorSeverity INT; 
     DECLARE @ErrorState INT; 

     SELECT @ErrorMessage = ERROR_PROCEDURE() + ': ' + ERROR_MESSAGE(), 
       @ErrorSeverity = ERROR_SEVERITY(), 
       @ErrorState = ERROR_STATE(); 

     RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState ,16,1) WITH LOG; 
     END CATCH 
    END 

這一切都工作得很好了幾天,但隨後記錄是不再在業務數據庫中更新和事件查看器告訴我,我得到的錯誤:

Error: 50000 Severity: 16 State: 1 After_Insert_T: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

我無法爲自己的生活弄清楚如何從我寫的SQL中獲取子查詢錯誤。我想也許V的觀點有一個子查詢,但事實並非如此。我在網上搜索,看到一個案例,實際系統複製表中的陳舊記錄導致SQL Server返回重複記錄,所以我檢查了所有基於複製的表,但沒有發現任何錯誤。

隨後而來的答案...

回答

1

的ERP供應商寫上,我被插入到表自己的觸發器。他的SQL有一個子查詢,在某些情況下會返回多行,但他沒有TRY/CATCH,所以它回到我的觸發器中的CATCH記錄了錯誤。我唯一還在疑惑的是,我認爲SET XACT_ABORT OFF聲明應該允許原來的記錄,儘管錯誤被寫入表,所以我重讀了幫助,並看到了這一點:

The THROW statement honors SET XACT_ABORT RAISERROR does not. New Applications should use THROW instead of RAISERROR.

我的CATCH例程幾乎從RAISERROR的幫助中複製,所以我錯過了這一點。

我從中得到的教訓是,僅僅因爲你的代碼報告了問題,不要認爲它是你造成的!

快樂編碼。

韋恩象牙
Wespine工業私人有限公司

+0

後來我注意到,我在RAISERROR語句中有多餘的額外的參數,但是這已在手的情況沒有影響與SQL Server似乎已經忽略了他們。 –

相關問題