您能否轻松有效地在触发器中复制或编辑INSERTED表?

时间:2016-05-05 18:43:55

标签: sql sql-server database triggers sql-server-2012

我正在编写一个触发器,我需要检查传入的数据并可能更改它。然后在触发器中我需要使用该新数据进行进一步处理。高度简化的版本看起来像这样:

        ALTER TRIGGER [db].[trig_update]
           ON  [db].[table]
           AFTER UPDATE
        AS
        BEGIN

            DECLARE @thisprofileID int

            IF (Inserted.profileID IS NULL)

            BEGIN

                SELECT  @thisprofileID=profileID
                FROM    db.otherTable
                WHERE   userid      = @thisuserID;

                UPDATE  db.table
                SET     profileID   = @thisprofileID
                WHERE   userid      = @thisuserID;

                -- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                -- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

            END

            IF ({conditional})

            BEGIN
                UPDATE db.thirdTable
                    SET [profileID] = Inserted.profileID
                        ...{20+ other fields}
                    FROM Inserted ...{a few joins}
                    WHERE {various criteria}
            END
        END

我们遇到的问题是update语句失败,因为Inserted.profileID为null,而thirdTable.profileID设置为不允许空值。 table.profileID永远不会保持为null;如果它被创建为null,则此触发器应捕获它并将其设置为值。但即使我们更新了'table',Inserted仍然具有null值。到目前为止,我觉得为什么会这样。

我不确定如何纠正这个问题。在带有注释X的区域中,我尝试对Inserted表运行更新查询以更新profileID,但这导致错误,因为伪表显然无法更新。这个假设我不正确吗?这将是一个简单的解决方案。

对我来说,下一个最合乎逻辑的解决方案是INSERT INTO表变量来制作Inserted的副本,然后在触发器的其余部分使用它,但由于未定义表变量,因此失败。定义该表变量将需要更多的字段而不是我想要计算的字段,并且在我们需要对“table”的结构进行更改时将会出现一个主要的维护噩梦。因此,假设这是最好的方法,是否有一种简单的方法可以将Inserted的数据结构复制到表变量中,而无需显式定义结构?

我不认为临时表(我可以轻易插入)是一个很好的解决方案,因为我的有限理解是它们比只存在于触发器内的表变量慢得多。我假设临时表也必须是公共的,并且如果我们的触发器触发两次并且两个实例都需要临时表,则会导致问题。

0 个答案:

没有答案