2

So, here is the conundrum I am trying to solve, let us say I have the following tables, scripted as create statements

create table table1 (pk int identity(1,1) primary key, a int, b int)
create table table2 (pk int identity(100,1) primary key, a int, b int)
create table tbllink (tbl1pk int, tbl2pk int)

now, due to some requirements oversight, I now find myself in a situation where I need to take some of the records from table1, insert them into table2 after performing some kind of ad hoc calculation, and I need to be able to link them back to each other via the bridge tbllink.

This is fairly easy to do with a cursor, see below for cursor pseudo

cursor for select pk, a, b from table1 where (some clause)
fetch cursor into @pk, @a, @b
while @@fetch_status
begin
insert into table2 (a, b)
    output @pk, inserted.pk into tbllink
values (@a, @b + 5)
fetch cursor into @pk, @a, @b
end

This works and gets me exactly the results I need, but what I would really like to be able to do is something like this.

insert into table2 (a, b)
   output table1.pk, inserted.pk into tbllink
select a, b + 5 from table1 where (some clause)

this doesn't compile, though. Is there any way to accomplish this, or should I just use the cursor? Thanks.

2
  • 1
    Nothing wrong with a cursor for a one-off job. I'd only worry about avoiding the cursor if you were going to build it into the system for all new inserts going forward. Commented Aug 18, 2015 at 18:14
  • You have it close. MERGE into tbl1 output into temp table, insert into table2 with additional calcs, then link in tbllink. a regular insert won't return the newly created identity Commented Aug 18, 2015 at 18:33

1 Answer 1

2

There's a way to use the MERGE statement to do this:

-- Setup
    create table #table1 (pk int identity(1,1) primary key, a int, b int)
    create table #table2 (pk int identity(100,1) primary key, a int, b int)
    create table #tbllink (tbl1pk int, tbl2pk int)
    INSERT INTO #table1 (a,b) VALUES (1,2)

-- Load
    MERGE INTO #Table2 t USING (SELECT pk, a, b from #Table1) s ON 1 = 0
    WHEN NOT MATCHED THEN
    INSERT 
      (
        a,
        b
      )
    VALUES 
      (
        a,
        b
      )
    OUTPUT s.PK, inserted.PK
    INTO #TblLink (Tbl1pk, Tbl2pk);

-- Verify
    SELECT * FROM #table1
    SELECT * FROM #table2
    SELECT * FROM #tbllink

-- Clean up
    DROP TABLE #table1
    DROP TABLE #table2
    DROP TABLE #tbllink
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this was very helpful

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.