2010-11-14 64 views
2

我有以下的情況(SQL Server Express的):通過PK-FK約束 SQL Server觸發器表與外鍵

  • 是連接這兩個表的視圖連接

    • 2表
    • 的程序使用的數據庫僅有權訪問對視圖的視圖的
    • 一個代替觸發器插入件

    的想法是,三gger將數據輸入到表格中 - >通過IDENTITY創建一個新的PK,第二個表格現在必須包含1.表格的ID作爲其主鍵的一部分...

    如何訪問新創建的1.在多連接環境中的表的PK?這是數據庫的簡化/體改版本:

    CREATE TABLE Training ( 
    Training_ID INT IDENTITY NOT NULL PRIMARY KEY, 
    Name NVARCHAR(30) NOT NULL); 
    
    CREATE TABLE Kilometer (
    Training_ID INT NOT NULL REFERENCES Training(Training_ID), 
    Kilometer_ID INT NOT NULL, 
    Timestamp DATETIME NOT NULL, 
    PRIMARY KEY(Training_ID, Kilometer_ID); 
    
    CREATE VIEW TrainingView ( 
    SELECT t.Name, k.Timestamp 
    FROM Training t LEFT JOIN Kilometer k ON (t.Training_ID = k.Training_ID)); 
    
    CREATE TRIGGER TrainingTrigger ON TrainingView INSTEAD OF INSERT AS BEGIN 
    INSERT INTO Training(Name) SELECT Name FROM inserted; 
    INSERT INTO Kilometer(Training_ID, Kilometer_ID, Timestamp) SELECT @@Identity, 0, Timestamp FROM inserted; 
    END; 
    

    爲Kilometer_ID默認的「0」是強制性的,由於在數據庫中的其他定義,合併這兩個表是不是一個選項... 雖然觸發似乎功能正確,我不確定它是否會在多用戶環境中發生(@@ Identity,如果另一個連接改變了表格)?

    是否有更好的解決方案來觸發此觸發器?

    格爾茨邁克爾

  • 回答

    2

    如果用@@認同你的關心是唯一的問題,使用SCOPE_IDENTITY(),它返回最近創建的ID從同一範圍。

    差異來解釋這裏:http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/

    +0

    感謝您的鏈接,您對設計有任何其他擔憂嗎? – MFH 2010-11-14 17:52:28

    +0

    我可能只是爲兩個插入存儲了一個過程,但是您的觸發器看起來很健康。我不確定我是否真的得到了表格的內容,但只要不介意你不能在一個語句中插入多行,就像Matt解釋的那樣,結構看起來很好。 – 2010-11-14 18:08:24

    +0

    好吧,我可能已經過分簡化了示例代碼,在一個語句中插入多行並不是真的需要當前(至少根據當前要求:)) – MFH 2010-11-14 19:55:50

    0

    你的方法可能是去上班幾乎所有的時間,如果它在單個刀片的低容積環境。在SQL Server中,如果使用SCOPE_IDENTITY更好,因爲它只從當前範圍獲取身份。

    如果您想一次插入多行(例如,insert into TrainingView select ...),這將會中斷,因爲您需要多個TrainingID。爲此,您可以使用SQL Server's OUTPUT clause來獲取該插入的所有ID。

    +0

    感謝您的回答,我會更好地更新到SCOPE_IDENTITY。如果我理解正確,那麼函數將返回觸發器創建的最後一個標識,而不管觸發器並行執行的頻率如何或數據庫中的其他位置更新了標識。我對嗎? – MFH 2010-11-14 17:59:38

    +0

    我不確定你的意思。 SCOPE_IDENTITY()將返回特定會話中插入的特定例程的最後一個標識,而不管數據庫中發生了什麼或者需要多長時間調用SCOPE_IDENTITY。所以,如果你插入但是讓你的窗口/連接保持打開狀態,其他人插入,那麼你會調用SCOPE_IDENTITY(),你會得到你最後插入的ID而不是他們的。 – Matt 2010-11-24 22:33:13