【问题标题】:Insert OUTPUT Insert.id to another table in multiple values insert将 OUTPUT Insert.id 插入到另一个表中的多个值插入
【发布时间】:2014-10-16 09:02:32
【问题描述】:

为了简单起见,假设我有两张桌子

user table (id, email)

user log table (id, date)

无论 id 被插入到 user 表中,相同的 id 应该被插入到 user_log 表中,否则事务应该失败。

我该怎么做

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

【问题讨论】:

  • 这可能是实现触发器的理想选择。你考虑过这种方法吗?

标签: sql-server sqltransaction multiple-insert


【解决方案1】:

您可以将输出直接插入到 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 感谢您的简短回答。我现在如何返回插入的 ID?
【解决方案2】:

方法 1 - 使用 OUTPUT 的“双插入”

优点:单语句,无隐藏触发器(方法 2)。

缺点: 仅适用于 this 语句,即不捕获所有插入事件

INSERT INTO dbo.users (id)
  OUTPUT inserted.id
  INTO user_log (id)
VALUES (9)
     , (3)
     , (7)
;

方法 2 - 触发器

优点:捕获所有插入事件

缺点:触发器是“隐藏”机制

CREATE TRIGGER user_log_after_insert
  ON dbo.users
    AFTER INSERT
  AS
BEGIN
  INSERT INTO dbo.user_log (id)
  SELECT id
  FROM   inserted
  ;
END
;

方法 3 - 临时表

包含在使用不支持方法 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-17
    • 2012-03-06
    • 2014-07-29
    • 2014-04-29
    • 1970-01-01
    • 2014-05-22
    相关资源
    最近更新 更多