我在数据库中的视图上创建了一个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。答案 0 :(得分:4)
在INSERT语句中,每个列都会受到影响。它要么是NULL,要么是你指定的值。
检查NULL是最好的选择,但是你不能这样做,我想你可能会有点卡住。你能解决可能需要明确处理NULL的场景吗?
答案 1 :(得分:2)
对于INSERT,一切都是变化,因为它是一个新行。
如果您有AFTER触发器,则可以测试插入的值是否为默认值。如果默认值为NULL(例如可以为空且无默认值),那么如何区分是否在任何触发器中显式插入NULL?
在BEFORE触发器中,我不知道您是否可以捕获默认值。当然,如果默认值为NEWID(),这仍然无法帮助您。
从表面上看,这不能在触发器中完成。