SQL触发器&插入的Idenities

时间:2012-09-12 04:14:21

标签: sql sql-server triggers

我遇到了一个我无法解决的触发器问题。

假设我有两张桌子,Stu_Table2& Stu_log。 Stu_table2有一些列,其中一列是自动生成的主键[stu_id]。两个表之间的链接是[stu_name] = [user_id]

以下代码适用于Updates&删除(因为主键已存在)。但是我坚持插入 - 如果尚未生成,我如何将自动生成的主键从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]=@stu_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]=@stu_id
                END
        END 

HELP!

1 个答案:

答案 0 :(得分: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. 我从[user_id] = @stu_id删除了无意义的UPDATE设置。鉴于此更新的WHERE子句(或上面的我的连接等效),这两个必须已经相等。