【发布时间】:2009-05-25 22:25:32
【问题描述】:
我有一个表,我在其中创建了一个 INSTEAD OF 触发器来执行一些业务规则。
问题是当我将数据插入此表时,SCOPE_IDENTITY() 返回一个 NULL 值,而不是实际插入的标识。
插入 + 范围代码
INSERT INTO [dbo].[Payment]([DateFrom], [DateTo], [CustomerId], [AdminId])
VALUES ('2009-01-20', '2009-01-31', 6, 1)
SELECT SCOPE_IDENTITY()
触发器:
CREATE TRIGGER [dbo].[TR_Payments_Insert]
ON [dbo].[Payment]
INSTEAD OF INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF NOT EXISTS(SELECT 1 FROM dbo.Payment p
INNER JOIN Inserted i ON p.CustomerId = i.CustomerId
WHERE (i.DateFrom >= p.DateFrom AND i.DateFrom <= p.DateTo) OR (i.DateTo >= p.DateFrom AND i.DateTo <= p.DateTo)
) AND NOT EXISTS (SELECT 1 FROM Inserted p
INNER JOIN Inserted i ON p.CustomerId = i.CustomerId
WHERE (i.DateFrom <> p.DateFrom AND i.DateTo <> p.DateTo) AND
((i.DateFrom >= p.DateFrom AND i.DateFrom <= p.DateTo) OR (i.DateTo >= p.DateFrom AND i.DateTo <= p.DateTo))
)
BEGIN
INSERT INTO dbo.Payment (DateFrom, DateTo, CustomerId, AdminId)
SELECT DateFrom, DateTo, CustomerId, AdminId
FROM Inserted
END
ELSE
BEGIN
ROLLBACK TRANSACTION
END
END
代码在创建此触发器之前工作。我在 C# 中使用 LINQ to SQL。我看不到将SCOPE_IDENTITY 更改为@@IDENTITY 的方法。我该如何完成这项工作?
【问题讨论】:
-
我认为这个表在您插入 INSTEAD OF 语句之前就已经工作了吗?您是否检查了主键字段以确保它具有身份规范?
-
是的,确实如此(您现在可以看到代码 - 它确实插入了一行,并且在插入时确实获得了自动标识)。
-
为什么不使用在不满足规则时产生错误的 BEFORE INSERT 触发器,而不是使用 INSTEAD OF?
-
@araqnid - 因为据我所知 SQL Server 没有这样的东西 - 虽然我必须承认我没有直接尝试过,但基于谷歌搜索,当然可能是我发现了无效或过时的资源——真的有这样的东西吗?
-
我们在 SQL Server 2000 中使用了这样的触发器——这似乎是默认模式,只是将触发器声明为“在 dbo.tablename 上创建触发器 TG_xxx 以进行插入,更新为 ....” .我们有逻辑来测试条件并调用“raiserror()”,然后在验证失败时执行“回滚事务”。话虽如此,我们使用 SP 来生成 ID 而不是身份——这可能就是为什么,坚持我们这样做的人对推理有点含糊。但后来他在实施 scope_identity() 之前就养成了这个习惯。
标签: sql-server tsql linq-to-sql sql-server-2008