MS SQL Server没有行级触发器,对吗?如果我需要在触发器中插入一行然后插入另一行,根据第一次插入的结果,光标是否是最佳解决方案?
例如,有没有更好的方法:
CREATE TABLE t1 (foo int)
CREATE TABLE t2 (id int IDENTITY, foo int)
CREATE TABLE t3 (t2_id int)
GO
CREATE TRIGGER t1_insert_trg ON t1 FOR INSERT AS
DECLARE c CURSOR FOR
SELECT foo FROM inserted
DECLARE @foo int
OPEN c
FETCH NEXT FROM c INTO @foo
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO t2 (foo) VALUES (@foo)
INSERT INTO t3 (t2_id) VALUES (@@IDENTITY)
FETCH NEXT FROM c INTO @foo
END
CLOSE c
DEALLOCATE c
答案 0 :(得分:3)
我认为你是在2005年还是更好?如果是这样,查看OUTPUT子句,您不应该需要行级触发器。例如:
USE tempdb;
GO
CREATE TABLE t1 (foo int);
CREATE TABLE t2 (id int IDENTITY, foo int);
CREATE TABLE t3 (t2_id int);
GO
CREATE TRIGGER t1_insert ON t1
FOR INSERT AS
BEGIN
DECLARE @new_rows TABLE(new_id INT, old_foo INT);
INSERT t2(foo)
OUTPUT inserted.id, inserted.foo
INTO @new_rows
SELECT foo
FROM inserted;
INSERT t3 SELECT new_id FROM @new_rows;
END
GO
INSERT t1(foo) SELECT 1 UNION ALL SELECT 5;
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
GO
DROP TABLE t1,t2,t3;
您也可以通过在T1上插入一个插入T2的触发器,然后在T2上插入一个插入T3的触发器来管理它。这不会像IMHO那样高效,并且不容易管理,但我会提出它更容易遵循(如果你被困在2000,可能是你唯一的选择)。两者都可以基于集合,不需要游标或任何其他逐行处理方法。
USE tempdb;
GO
CREATE TABLE t1 (foo int);
CREATE TABLE t2 (id int IDENTITY, foo int);
CREATE TABLE t3 (t2_id int);
GO
CREATE TRIGGER t1_insert ON t1
FOR INSERT AS
BEGIN
INSERT t2(foo)
SELECT foo FROM inserted;
END
GO
CREATE TRIGGER t2_insert ON t2
FOR INSERT AS
BEGIN
INSERT t3(t2_id)
SELECT id FROM inserted;
END
GO
INSERT t1(foo) SELECT 1 UNION ALL SELECT 5;
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
GO
DROP TABLE t1,t2,t3;
(顺便说一句,如果您要使用身份值,请使用SCOPE_IDENTITY(),而不是@@ IDENTITY。)
答案 1 :(得分:2)
您可以使用以下插入来避免游标或需要知道插入的标识。
Insert INTO t2 (foo) Select foo from inserted
Insert into t3 (t2_id) Select t2.id from t2
inner join inserted i on t2.foo = i.foo
答案 2 :(得分:1)
为什么不级联触发器 - 使用T2上的INSERT触发器在T3上执行插入。然后你可以避开t1_insert_trg中的光标,只需使用inserted - 如:
CREATE TRIGGER t1_insert_trg ON t1 FOR INSERT AS
INSERT INTO t2
SELECT foo FROM inserted -- fires t2 INSERTED trigger
CREATE TRIGGER t2_insert_trg ON t2 FOR INSERT AS
INSERT INTO t3
SELECT id FROM inserted