为简单起见假设我有两张桌子
user table (id, email)
user log table (id, date)
无论在用户表中插入什么id,都应该在user_log表中插入相同的id,否则事务应该失败。
我该怎么做
BEGIN TRANSACTION
INSERT into user(id, email) OUTPUT Inserted.id (1, 'a@x.com', 'x'), (2, 'b@x.com', 'y')
// I also want to be able to do
INSERT into user_log(id, date) values(1, date), (2, date)
COMMIT TRANSACTION
答案 0 :(得分:6)
您可以将输出直接插入user_log表:
BEGIN TRANSACTION
INSERT INTO [User] (ID, Email)
OUTPUT inserted.id, CURRENT_TIMESTAMP INTO user_log(id, date)
VALUES (1, 'a@x.com'), (2, 'b@x.com');
COMMIT TRANSACTION
<强> Example on SQL Fiddle 强>
如果您需要返回ID,可以添加第二个OUTPUT
子句:
BEGIN TRANSACTION
INSERT INTO [User] (ID, Email)
OUTPUT inserted.id, CURRENT_TIMESTAMP INTO user_log(id, date)
OUTPUT inserted.id
VALUES (1, 'a@x.com'), (2, 'b@x.com');
COMMIT TRANSACTION
答案 1 :(得分:0)
优点:单一陈述,没有隐藏的触发器(方法2)。
缺点:仅适用于此语句,即不捕获所有插入事件
INSERT INTO dbo.users (id)
OUTPUT inserted.id
INTO user_log (id)
VALUES (9)
, (3)
, (7)
;
优点:捕获所有插入事件
缺点:触发器是“隐藏”机制
CREATE TRIGGER user_log_after_insert
ON dbo.users
AFTER INSERT
AS
BEGIN
INSERT INTO dbo.user_log (id)
SELECT id
FROM inserted
;
END
;
包含在使用不支持方法1的旧版SQL Server时的完整性
CREATE TABLE #temp (
id int
);
INSERT INTO #temp (id) VALUES (9);
INSERT INTO #temp (id) VALUES (3);
INSERT INTO #temp (id) VALUES (7);
BEGIN TRAN
INSERT INTO dbo.users (id)
SELECT id
FROM #temp
;
INSERT INTO dbo.user_log (id)
SELECT id
FROM #temp
;
COMMIT TRAN