2012-09-12 92 views
1

我遇到了一個我無法弄清的觸發器的問題。SQL觸發器和插入的代碼

假設我有兩個表,Stu_Table2 & Stu_log。 Stu_table2有一些列,其中一列是自動生成的主鍵[stu_id]。兩個表格之間的鏈接是[stu_name] = [user_id]

以下代碼適用於更新&刪除(因爲主鍵已存在)。但我堅持插入 - 如何將自動生成的主鍵從stu_name插入日誌表,如果它尚未生成?

Stu_name列,[stu_id] [Stu_name] [Stu_class]

Stu_log列,[USER_ID] [stu_name]

顯然這不是一個現實世界的例子,只是測試概念證明。

ALTER TRIGGER [dbo].[stu_testtrigger] 
    ON [dbo].[Stu_Table2] FOR INSERT, UPDATE, DELETE 
    AS 

    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with caller queries SELECT statements. 
    -- If an update/insert/delete occurs on the main table, the number of   records   affected 
    -- should only be based on that table and not what records the triggers may/may not 
    -- select. 
    SET NOCOUNT ON; 

    -- 
    -- Variables Needed for this Trigger 
    -- 
    DECLARE @stu_ID int 
    DECLARE @stu_name varchar(15) 
    DECLARE @stu_class int 

    -- 
    -- Determine if this is an INSERT,UPDATE, or DELETE Action 
    -- 
    DECLARE @Action as char(1) 
    DECLARE @Count as int 
    SET @Action = 'I' -- Set Action to 'I'nsert by default. 
    SELECT @Count = COUNT(*) FROM DELETED 
    if @Count > 0 
     BEGIN 
      SET @Action = 'D' -- Set Action to 'D'eleted. 
      SELECT @Count = COUNT(*) FROM INSERTED 
      IF @Count > 0 
       SET @Action = 'U' -- Set Action to 'U'pdated. 
     END 

    if @Action = 'D' 
     -- This is a DELETE Record Action 
     -- 
     BEGIN 
      SELECT @Stu_id =[stu_id] 
         ,@Stu_name = [stu_name] 
      FROM DELETED 

      DELETE [dbo].[stu_log] 
      WHERE [user_id][email protected]_id 
     END 
    Else 
     BEGIN 
       -- 
       -- Table INSERTED is common to both the INSERT, UPDATE trigger 
       -- 
       SELECT @stu_id =[stu_id] 
        ,@stu_name = [stu_name] 
       FROM INSERTED 

      if @Action = 'I' 
       -- This is an Insert Record Action 
       -- 

       --THIS IS WHERE I'm STUCK i think!!! 
       BEGIN 
        INSERT INTO [stu_log] 
         ([user_id] 
         ,[description]) 
        VALUES 
         (@stu_id 
         ,@stu_name) 

       END 
      else 
       -- This is an Update Record Action 
       -- 
       BEGIN 
        UPDATE [stu_log] 
         SET [user_id] = @stu_id 
           ,[description] = @Stu_name 
         WHERE [user_id][email protected]_id 
       END 
     END 

幫助!

+0

「插入的」表也包含主鍵列的值。你在'@Action ='I''塊中找不到它嗎? – Vikdor

+0

@Vikdor說,Inserted應該有stu_id,即使它是一個IDENTITY()自動生成的值。你確切的問題是什麼? (錯誤,是空還是...?) –

+0

「stu_log」的*點*是什麼?它似乎只是'stu_table2'中兩列的副本,因爲這個觸發器會使它們保持同步。爲什麼不只是有一個觀點,如果你試圖隱藏'stu_class'的東西。另外,你的觸發器很壞,因爲'inserted'可以包含多行。這意味着未定義「SELECT @ Var1 = Column1,@ Var2 =來自插入的Column2」的結果。你甚至可以發現,這兩個變量最終會得到來自不同行的值(理論上至少)。 –

回答

1

由於您似乎想要針對插入,更新和刪除執行截然不同的操作,因此我不確定爲什麼要將所有操作鎖定到單個觸發器中。我只是有:

CREATE TRIGGER [dbo].[stu_testtrigger_I] 
ON [dbo].[Stu_Table2] AFTER INSERT 
AS 
    INSERT INTO stu_log ([user_id],[description]) 
    SELECT stu_id,stu_name from inserted 
GO 
CREATE TRIGGER [dbo].[stu_testtrigger_D] 
ON [dbo].[Stu_Table2] AFTER DELETE 
AS 
    DELETE FROM stu_log WHERE [user_id] IN (
    SELECT stu_id from deleted) 
GO 
CREATE TRIGGER [dbo].[stu_testtrigger_U] 
ON [dbo].[Stu_Table2] AFTER UPDATE 
AS 
    UPDATE l SET user_name = i.user_name 
    FROM 
     stu_log l 
     inner join 
     inserted i 
     on l.[user_id] = i.stu_id 
GO 

注:

  1. 這適用於多行插入,更新和刪除,其原來的沒有
  2. 我已經說過AFTER而不是FOR ,以便更清楚地知道這些操作在Stu_Table2中的任何活動已經發生後發生(例如身份值已經生成,這似乎是您的擔憂)。
  3. 但是,您應該注意,AFTERFOR是同義詞。如果我們正在執行INSTEAD OF觸發器,您只會得到不同的行爲。
  4. 我從UPDATE中刪除了無意義的[user_id] = @stu_id設置。鑑於此更新的WHERE條款(或上面的我的連接等效條款),這兩者必須已經相同。