【问题标题】:SQL Server: INSERT INTO 2 tablesSQL Server:插入 2 个表
【发布时间】:2017-09-14 18:26:27
【问题描述】:

当我在PERSONS 表中添加一条记录时,ID 列会自动递增(标识)。

我需要这个 ID 来在ADDRESS 表中插入一条记录,这样我就可以同时加入它们。

当我有多行要追加时,有谁知道如何让这个ID 在第二个语句中使用?

基本上它会追加一行并使用 ID 将行追加到另一个表中。

我想避免循环每条记录来执行此操作。

提前谢谢你。

INSERT INTO PERSONS (FIRST_NAME, LAST_NAME)
    SELECT FIRST_NAME, LAST_NAME 
    FROM CONTACTS

INSERT INTO ADDRESS (PERSON_ID)
    SELECT ID 
    FROM PERSONS

【问题讨论】:

  • 一种方法是使用触发器。
  • 有一个非常标准的模式,使用 MERGE 语句,或者使用 OUTPUT 语句到临时表并从中插入子表。
  • 在您的第一次插入中,您插入了我假设的多行......并且您想将这些相同的行(来自 Persons 表的 ID)插入到地址表中?如果它是一条记录,那么它是可管理的,否则我和@GordonLinoff 一起使用触发器。真的只是使用触发器,因为这就是它的用途。
  • @scsimon - OUTPUT INSERTED ... INTO 是为了这个确切且唯一的目的,所以按照这个逻辑,他们应该使用它。
  • 是的@MartinSmith,但有problems with MERGE 已与Microsoft 记录在案,我不愿意打赌没有出现更多。

标签: sql sql-server select insert-into


【解决方案1】:

您可以使用INSERT ... OUTPUT INSERTED ... INTO

INSERT @PERSONS
       (FIRST_NAME,
        LAST_NAME)
OUTPUT Inserted.Id
INTO @ADDRESS
SELECT *
FROM   @CONTACTS; 

或者如果您的需求更复杂,另一种可能性是合并语句

DECLARE @CONTACTS table ( FIRST_NAME  varchar(50) , LAST_NAME varchar(50))
DECLARE @PERSONS table  (Id int identity , FIRST_NAME  varchar(50) , LAST_NAME varchar(50))
DECLARE @ADDRESS table  (PERSON_ID int)

INSERT @CONTACTS VALUES ('FIRST_NAME1' , 'LAST_NAME2'),  ('FIRST_NAME1' , 'LAST_NAME2');

MERGE @PERSONS t
using @CONTACTS s
on
t.FIRST_NAME = s.FIRST_NAME 
AND t.LAST_NAME = s.LAST_NAME
WHEN NOT MATCHED THEN INSERT (FIRST_NAME, LAST_NAME ) Values (s.FIRST_NAME , s.LAST_NAME)
OUTPUT Inserted.Id into @ADDRESS;

餐桌人

select * from @PERSONS
Id          FIRST_NAME                                         LAST_NAME
----------- -------------------------------------------------- --------------------------------------------------
1           FIRST_NAME1                                        LAST_NAME2
2           FIRST_NAME1                                        LAST_NAME2

表格地址

SELECT * from @ADDRESS
PERSON_ID
-----------
1
2

【讨论】:

  • 我看不到问题中对插入(如果不存在)和 MERGE 的任何要求,而不是普通的INSERT ... OUTPUT
  • 批量插入时,无法创建标识。一个选项创建一个触发器,但在某些情况下它不是一个选项。在合并语句上,您可以获得要使用的输出。
  • 插入也存在输出子句。
  • 感谢大家的帮助。没有真正与合并和触发器一起使用。我尝试了 OUTPUT Inserted 但它没有返回我想要的结果。我会从这一切中找出一些东西。
【解决方案2】:

为了可视化@GordonLinoff 和@scsimon 给出的答案,我创建了一个小的demo。您可以查看完整的 Microsoft 触发器指南here

DDL

CREATE TABLE CONTACTS ( FIRST_NAME varchar(50) , LAST_NAME varchar(50) ); GO CREATE TABLE PERSONS ( Id int IDENTITY(1,1) , FIRST_NAME varchar(50) , LAST_NAME varchar(50) ); GO CREATE TABLE ADDRESS ( PERSON_ID int ); GO CREATE TRIGGER TR_AI_Persons_PersonAddress ON PERSONS AFTER INSERT AS BEGIN INSERT INTO ADDRESS (PERSON_ID) SELECT Id FROM inserted END

DML INSERT INTO CONTACTS(FIRST_NAME, LAST_NAME) VALUES('Bob', 'White'); INSERT INTO CONTACTS(FIRST_NAME, LAST_NAME) VALUES('Tom', 'Black'); INSERT INTO PERSONS (FIRST_NAME, LAST_NAME) SELECT FIRST_NAME, LAST_NAME FROM CONTACTS;
SELECT * FROM ADDRESS;

【讨论】:

  • 感谢您的帮助。没有真正与触发器一起使用。我尝试了 OUTPUT Inserted 但它没有返回我想要的结果。我会从这一切中找出一些东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
相关资源
最近更新 更多