2012-01-08 170 views
1

我有一個關於SQL約束的問題,準確地說在transact-sql中。我有一個旅行數據庫。我創建了添加新旅行參與者的過程。我使用ms-sql服務器,因此在創建表時添加了外鍵和主鍵約束。現在在我的添加新的參與者一趟程序我有檢查sql約束

insert VoyageThemes(VoyageId,ThemeId) values (@voyageId,@themeId) 

現在,在VoyageThemes表都VoyageId和的ThemeID是主鍵和外鍵,以便doesen't對應,當我嘗試添加新值數據庫約束中已經存在的值引發了這個問題。

我的問題是,我可以以某種方式檢查是否約束'說'我不能將值添加到表,所以我可以停止該過程,或者如果VoyageId和ThemeId存在,我需要手動檢查我的數據庫。

我需要知道,如果這些值存在,因爲這行代碼:

update Voyages 
set [email protected]*@numOfParticipants 

我更新旅行的價格,所以這行代碼只能excecute只要有相應的VoyageId和的ThemeID

+0

我相信你可以在插入後檢查@@ ROWCOUNT,看看它是否成功。 – rene 2012-01-08 21:24:55

+0

看看http://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-foreign-key-relationships-and-name-of-the-constraint-for-each- table-in-database /。它有你需要的所有信息(你可能還想將'REFERENTIAL_CONSTRAINTS.UPDATE_RULE,REFERENTIAL_CONSTRAINTS.DELETE_RULE'添加到原始查詢中) – a1ex07 2012-01-08 21:31:31

+1

你從哪裏得到你試圖插入到這個表中的值?它看起來像你有一個PK themeId的主題表和PK voyageId和VoyageThemes的航程表是一個連接或多對多表。在大多數應用程序中,當您添加一個或另一個或將兩者連接在一起時,您會從某個現有主題和/或航程列表中選擇某種屏幕,在這種情況下,您的中間應用層位於最少會知道提交給你的數據庫的正確的PK ID ......所以你的問題可能是一個更大的應用程序設計問題的指示? – tnktnk 2012-01-08 22:20:36

回答

2

我想你可以使用一個try/catch?:

... 
BEGIN TRY 
    insert VoyageThemes(VoyageId,ThemeId) values (@voyageId,@themeId)  
    -- If we are here, then the insert succeeded, proceed with the update 
    update Voyages 
    set [email protected]*@numOfParticipants 
    ... 
END TRY 
BEGIN CATCH 
    -- insert failed, check error 
    SELECT @error_number = ERROR_NUMBER(), 
      @error_severity = ERROR_SEVERITY(), 
      @error_state = ERROR_STATE() 
    IF @error_number = 547 
    -- constraint violation 
     BEGIN  
      PRINT '...' 
     END 
    ELSE 
     -- propagate error 
     BEGIN 
      RAISERROR(@error_number, @error_severity, @error_state) WITH LOG 
     END 
END CATCH 
+0

這會導致'UPDATE'失敗。在預先存在的行的情況下,我認爲他們只想「故障切換」INSERT並允許「UPDATE」。 – onedaywhen 2012-01-09 09:46:09

+0

@onedaywhen我不這麼認爲,我認爲他們想要更新航程價格*只有當主題是新的*。否則,主題價格已經包含在航程價格中。 – gpeche 2012-01-09 19:59:41

1

不是INSERT,使用MERGE只有當它不創建一個行已經存在於

MERGE INTO VoyageThemes 
    USING (
      VALUES (@voyageId, @themeId) 
     ) AS S (VoyageId, ThemeId) 
     ON VoyageThemes.VoyageId = S.VoyageId 
     AND VoyageThemes.ThemeId = S.ThemeId 
WHEN NOT MATCHED THEN 
    INSERT (VoyageId, ThemeId) 
     VALUES (VoyageId, ThemeId);