INSERT TRIGGERS和UPDATE()函数

时间:2010-01-18 04:31:45

标签: sql-server sql-server-2005 tsql triggers

我在数据库中的视图上创建了一个INSTEAD OF INSERT触发器。我想知道视图上INSERT语句的列列表中包含哪些列。

如果您阅读触发器的MSDN文档,则UPDATE()和COLUMNS_UPDATED()函数应满足此要求。但是,在我的测试期间,我发现无论INSERT列列表中的列是什么,UPDATE()和COLUMNS_UPDATED()函数总是返回视图中的所有列。

CREATE VIEW dbo.MyView (BatchId, [Status], OrderNumber, WhenClosed) AS
    SELECT bth.BatchId, bth.[Status], bth.OrderNumber,
            Private.ufxAdjustDateTime(bth.WhenClosed, bth.WhenClosedUtcOffset)
        FROM Private.Batch AS bth
GO
CREATE TRIGGER dbo.[MyView-Insert] ON dbo.MyView INSTEAD OF INSERT AS
BEGIN
    SET NOCOUNT ON

    DECLARE @batchIdIsSet BIT

    SELECT @batchIdIsSet = 0
    IF UPDATE(BatchId)
        SELECT @batchIdIsSet = 1

    INSERT INTO Private.Batch
        (BatchId, [Status], OrderNumber)
        SELECT CASE @batchIdSet
                   WHEN 1 THEN ins.BatchId
                   ELSE NEWID()
               END, ins.[Status], ins.OrderNumber
            FROM inserted AS ins
END

我想要这样做的原因是我需要修改现有的表,并且我有大量依赖它的遗留代码。所以我所做的就是创建一个新表,将旧表更改为视图并在视图上创建触发器,以允许INSERT,UPDATE和DELETE语句。

现在,旧表具有某些列的默认值,如果插入到视图中使用默认值我想在插入新表中使用默认值。为此,我必须能够找出哪些列[明确]为INSERT提供了值。

检查列是否为NULL是不够的,因为INSERT语句可以显式地将字段值设置为NULL,这是完全可以接受的。

嗯,我希望这很清楚。 KEP。

2 个答案:

答案 0 :(得分:4)

在INSERT语句中,每个列都会受到影响。它要么是NULL,要么是你指定的值。

检查NULL是最好的选择,但是你不能这样做,我想你可能会有点卡住。你能解决可能需要明确处理NULL的场景吗?

答案 1 :(得分:2)

对于INSERT,一切都是变化,因为它是一个新行。

如果您有AFTER触发器,则可以测试插入的值是否为默认值。如果默认值为NULL(例如可以为空且无默认值),那么如何区分是否在任何触发器中显式插入NULL?

在BEFORE触发器中,我不知道您是否可以捕获默认值。当然,如果默认值为NEWID(),这仍然无法帮助您。

从表面上看,这不能在触发器中完成。