开发者

Transact-sql insert in two tables at once?

Ok, this will sound weird, but can you do an insert in a join of two tables?

I have a table A and a table B with a foreign key to A. Now I want to copy multiple records of table A in one query + a copy of the records in table B with foreign key to the records being copied in table A (but as foreign key the new identities).

Hope somebody understands me. My other option is to use a cursor but if possible 开发者_开发知识库I would like to avoid this.


Another option is two queries.

Copy the records with the primary keys first, then copy the records with the foreign keys.


Ok, this will sound weird, but can you do an insert in a join of two tables?

The short answer is no; you can only insert into one table at a time.

The longer answer is that you can fudge it with a view or triggers, but if you're going to go that far, then why not just use a stored procedure (which will be easier to write, understand and maintain)?

Instead of a single statement, from a performance and reliability perspective, it sounds like what you really want to do is to use a single transaction. There are also some techniques that allow you to handle multiple-row inserts without resorting to cursors.

For your the details of your specific operation, it would help if you could post some sample code.


Here is an example, if you are trying to "insert into both tables" at once.

Transact-sql insert in two tables at once?

First some preparation, create tables etc..

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

Now a view on these two tables

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

And an instead of insert trigger on the view

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

So now it is possible to:

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')    

Verify with:

SELECT * FROM vAB ;


Pls no cursors...

You could just use an INSERT trigger on A that inserts into B. You would just run the query on A, the trigger would fire for each insert.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜