2011-10-28 50 views
1

我有一個視圖,它具有INSTEAD OF INSERT觸發器(在SQL Server 2005中)。當用戶插入到視圖中時,他們實際上正在插入並更新許多表。視圖非常複雜,不能有索引,所以不幸的是不受約束。使用RAISERROR在t-SQL中引發特定錯誤

該視圖正在從C#插入,使用代碼可能會有問題需要更改。此代碼使用捕獲主要和唯一鍵違反了以下內容:

try 
{ 
    ... // Insert into view 
} 
catch (SqlException ex) 
{ 
    if (ex.Number == 2627 || ex.Number == 2601) // Primary key exception, unique constraint violation 
    { 
     ... // Report the duplicate entry to the user 
    } 
    else 
    { 
     throw; 
    } 
} 

所以我的問題是:我可以用我的RAISERROR觸發器內創建具有數2627或2601個例外?

回答

1

號你必須等待THROW in the next release(也許)

只能扔你已經投入sys.messages(50000+),或用文字,讓50000或嵌入它的錯誤文本並改變你的C#。你不能扔錯誤小於50000

如果視圖太複雜以至於你不能使用DRI,那麼它也是複雜。此外,您將遇到併發問題:重疊調用在您推出自己的某個時候打破了您的「獨特性」。

+0

謝謝,很公平。我的理解是,如果模式綁定視圖沒有左連接,沒有聯合和沒有子查詢,則只能在SQL Server 2005中編入索引。在我看來,這些看法不一定太複雜。 – Paul

+0

@Paul:他們這樣做是因爲維護一個索引視圖需要對這些構造進行大量的處理。請參閱「爲什麼我不能在索引視圖中使用OUTER JOIN?」在http://msdn.microsoft.com/en-us/library/dd171921%28SQL.100%29.aspx – gbn

+0

對不起,我的意思是太複雜,不適合作爲一個視圖,不要太複雜的SQL Server維護一個索引根據。在我的情況下,視圖沒有外連接,但有一個子查詢,以便我可以根據ROW_NUMBER()函數的結果進行限制。 – Paul

0

我不確定你是否真的可以RAISE真正的主鍵違規。雖然你可以RAISE你自己的錯誤與你自己的消息,然後catch。這也可以讓您區分真正的主要違規行爲和您自己的違規行爲。

或許完成,這將是最原始的方式...

SQL代碼(也許TRIGGER定義)...

RAISERROR('Custom View Violation',16,1); 

C#...

try 
{ 
    //execute SP/Insert etc... 
} 
catch (SqlException ex) 
{ 
    if (ex.Message.Split('\r')[0] == "Custom View Violation") 
    { 
     //deal with your exception 
    } 
} 
+0

謝謝...這可能是我需要做的,如果提高主鍵錯誤無法完成。或者,我可以通過將兩個相同的值插入到具有主鍵的臨時表中來導致真正的主鍵違例......雖然這兩者看起來都有點不合適:-S – Paul

+0

@Paul是的,他們有點冒險 - 儘管我會說在我的文章中的方法比你提出的雙重INSERT更簡單。我也確信有一個更好的方法來提升錯誤並捕獲你的特定異常,所以最好在「RAISERROR」的入口和出口處進行讀取。 –

+0

是的,同意了。 [和一些更多的字符] – Paul