Transact-sql一次插入两个表中?

时间:2009-11-24 14:59:56

标签: sql sql-server-2008

好的,这听起来很奇怪,但是你可以在两个表的连接中插入吗?

我有一个表A和一个带有A外键的表B.现在我想在一个查询中复制表A的多个记录+表B中的记录副本,其中外键用于复制的记录表A(但作为外键的新标识)。

希望有人理解我。我的另一个选择是使用光标但如果可能的话我想避免这种情况。

4 个答案:

答案 0 :(得分:3)

另一种选择是两个查询。

首先使用主键复制记录,然后使用外键复制记录。

答案 1 :(得分:1)

以下是一个示例,如果您尝试“立即插入两个表格”。

view_model_01

首先做一些准备,创建表等。

CREATE TABLE Tbl_A (
     Tbl_A_ID int NOT NULL
                  PRIMARY KEY identity(1,1)
    ,A1 varchar(20)
    ,A2 varchar(20)
    ,A3 varchar(20)
    )
GO

CREATE TABLE Tbl_B (
     Tbl_B_ID int NOT NULL
                  PRIMARY KEY identity(1,1)
    ,Tbl_A_ID int NOT NULL
    ,B1 varchar(20)
    ,B2 varchar(20)
    )
GO    

ALTER TABLE TBL_B
ADD CONSTRAINT FK1_B FOREIGN KEY ( Tbl_A_ID ) REFERENCES TBL_A ( Tbl_A_ID )
GO

现在关于这两个表的视图

CREATE VIEW vAB (A1, A2, A3, B1, B2)
AS
    SELECT  a.A1, a.A2, a.A3, b.B1, b.B2
    FROM Tbl_A AS a
         JOIN Tbl_B AS b ON a.Tbl_A_ID = b.Tbl_a_ID
GO

而不是视图上的插入触发器

CREATE TRIGGER trigAB
ON vAB INSTEAD OF INSERT
AS
BEGIN
    SET NOCOUNT ON
    DECLARE @aid int

    SET @aid = coalesce((SELECT max(Tbl_A_ID) FROM Tbl_A),0)
    SET IDENTITY_INSERT Tbl_A ON
    ;
    WITH abc AS(
    SELECT  A1, A2, A3, B1, B2, row_number() OVER(ORDER BY a1,a2,a3,b1,b2) AS rn
    FROM INSERTED
    )    
    INSERT  INTO Tbl_A ( Tbl_A_ID, A1, A2, A3 )
      SELECT  @aid + [rn], A1, A2, A3 FROM abc

    SET IDENTITY_INSERT Tbl_A OFF

    ;
    WITH abc AS(
    SELECT  A1, A2, A3, B1, B2, row_number() OVER(ORDER BY a1,a2,a3,b1,b2) AS rn
    FROM INSERTED
    )    
    INSERT  INTO Tbl_B ( Tbl_A_ID, B1, B2 )
      SELECT  @aid + [rn], B1, B2 FROM abc

END

所以现在可以:

INSERT  INTO vAB ( a1, a2, a3, b1, b2 )
VALUES
 ('a1_1', 'a2_1', 'a3_1', 'b1_1', 'b2_1')
,('a1_2', 'a2_2', 'a3_2', 'b1_2', 'b2_2')        
,('a1_3', 'a2_3', 'a3_3', 'b1_3', 'b2_3')        
,('a1_4', 'a2_4', 'a3_4', 'b1_4', 'b2_4')        
,('a1_5', 'a2_5', 'a3_5', 'b1_5', 'b2_5')    

验证:

SELECT * FROM vAB ;

答案 2 :(得分:1)

  

好的,这听起来很奇怪,但是你可以   在两个表的连接中插入一个?

简短的回答是否定的;你一次只能插入一张桌子。

更长的答案是你可以用视图或触发器来捏造它,但是如果你要走那么远,那么为什么不使用存储过程(这将更容易编写,理解和维护)?

从性能和可靠性的角度来看,而不是单一的陈述,听起来你真正想要做的就是使用单个事务。还有一些技术允许您处理多行插入而无需使用游标。

有关具体操作的详细信息,如果您可以发布一些示例代码,将会有所帮助。

答案 3 :(得分:0)

请不要游标......

你可以在插入B的A上使用INSERT触发器。你只需在A上运行查询,触发器将为每个插入触发。