【问题标题】:Insert into 2 tables from a single select query using TSQL使用 SQL 从单个选择查询中插入 2 个表
【发布时间】:2015-04-22 18:40:04
【问题描述】:

我正在尝试从一个选择语句插入 3 个表。这是我想要做的:

insert into dbo.temp1 (name, location, city)
select name, location, city from mytable.

我希望在运行 select 语句后能够插入 3 个表,例如插入 temp1、temp2 和 temp3。

我该怎么做?谢谢。

【问题讨论】:

  • 你能确定表的数量吗?题名提到二,正文多次提到三。
  • 是不是每次给temp1加数据时总要给这三个表加数据?如果是这样,可以使用触发器。

标签: sql sql-server tsql


【解决方案1】:

您最多可以使用output 对 2 个表执行此操作:

insert into dbo.temp1 (name, location, city)
output inserted.name, inserted.location, inserted.city into temp2
select name, location, city from mytable

【讨论】:

  • 这是插入两个表的绝佳解决方案!
【解决方案2】:

你不能一步完成*

您可以做的是将初始查询插入#temp 表(或@table 变量)作为暂存区,然后从那里插入表中。将步骤包装在事务中以保留 ACID:

   BEGIN TRAN

   select name, location, city 
       into #TEMP
       from mytable;

   insert into temp1(name, location, city)
     select name, location, city 
     from #TEMP;

    -- Same for temp2 and temp3.

   COMMIT TRAN

* 不包括诸如带有替代触发器的视图之类的黑客攻击。

从并发的角度来看,临时表很重要,因为如果源表有临时并发更改,重复原始查询 3 次可能会导致不同的结果。

【讨论】:

    【解决方案3】:

    你可以。 用一招。

    创建一个视图,然后在该视图上创建一个“instead of”触发器以将内容插入表中。如果您现在插入到您的视图中,您最终会在 3 个表中插入数据。这是一个演示

    -- 1. create 3 test tables
    create table t1( id int, f1 varchar(20))
    create table t2( id int, f2 varchar(20))
    create table t3( id int, f3 varchar(20))
    go
    
    -- 2. create the view
    create view Tt as
      select t1.ID, t1.f1, t2.f2,t3.f3
        from t1 
        join t2 on t1.ID=t2.ID 
        join t3 on t1.ID=t3.id
    go
    
    -- 3. create the trigger
    create trigger Tr_Test on Tt INSTEAD OF INSERT
    AS 
    BEGIN
      SET NOCOUNT ON;
      insert into t1 select id,f1 from inserted
      insert into t2 select id,f2 from inserted
      insert into t3 select id,f3 from inserted
    END
    GO
    
    -- 4. now do your insert with a single select 
    insert into tt 
      select 1,'A','B','C'
    
    -- 5. and watch the 3 tables
    select * from t1
    select * from t2
    select * from t3
    

    瞧,一个插入,3 个表被修改。我们不计算隐藏触发器,对吗;-)

    【讨论】:

      【解决方案4】:

      没有办法通过一个查询插入到 X 表中(好吧,插入并输出到表中)。

      所以你必须编写 3 个查询。


      或者您可以使用动态查询生成 SQL 语句。

      【讨论】:

        【解决方案5】:

        我不相信您可以在一个语句中插入多个表。但是,您绝对可以在一笔交易中完成。

        BEGIN TRANSACTION
            INSERT INTO dbo.temp1 (name, location, city)
            SELECT name, location, city 
              FROM myTable
            INSERT INTO dbo.temp2 (name, location, city)
            SELECT name, location, city
              FROM myTable2
        COMMIT TRANSACTION
        

        【讨论】:

          【解决方案6】:

          您可以使用 TRIGGER 使用一个 select 语句插入多个表。

          CREATE TRIGGER TEMP2_TEMP3_INSERT ON TEMP1
            AFTER INSERT AS
          BEGIN
            /* create your insert statements for TEMP2 and TEMP3 here
            referencing the data from the first insert */
          END;
          GO
          

          【讨论】:

            【解决方案7】:

            MySQL 不支持在单个 INSERT statement 中插入多表。奇怪的是,Oracle 是我所知道的唯一一个这样做的...

            但是,您可以使用一个事务并将它们都包含在一个事务中。

            MySQL:

            START TRANSACTION;
              INSERT INTO table1 VALUES ('1','2','3');
              INSERT INTO table2 VALUES ('1','2','3');
            COMMIT;
            

            SQL 服务器:

            BEGIN TRAN;
              INSERT INTO table1 VALUES ('1','2','3');
              INSERT INTO table2 VALUES ('1','2','3');
            COMMIT;
            

            具有错误捕获/回滚功能的 SQL Server:

            BEGIN TRANSACTION [Tran1]
            
              BEGIN TRY
            
                INSERT INTO table1 VALUES ('1','2','3')    
                INSERT INTO table2 VALUES ('1','2','3')  
            
            
                COMMIT TRANSACTION [Tran1]
            
              END TRY
              BEGIN CATCH
                ROLLBACK TRANSACTION [Tran1]
              END CATCH  
            
            GO
            

            【讨论】:

              猜你喜欢
              • 2012-10-15
              • 2013-12-14
              • 2018-07-27
              • 1970-01-01
              • 1970-01-01
              • 2013-11-15
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多