I have ‘inherited‘ a brilliant piece of TSQL code that does this:
- Loops row-by-row over a cursor.
- The cursor contains data that need to be merged (Upserted) in Table A
- For each row loop in the cursor a stored proc is called. The proc:
- If a corresponding row exists in Table A then it is updated
- If such a row does not exist then:
- Inserts a single row in in a different Table B.
- Fetches the newly generated ID (say its called IDB)
- Inserts a single row in Table A. Table A insertions need an IDB (the field is not null, it is supposed to have values ONLY from table B, but no FK constraint is in place)
Obviously this sucks (performance & elegance reasons)!!
Question
At first this looks like a standard case of MERGE usage. I tried doing:
MERGE [dbo].[TableA] AS Target
USING <cursor data set as a select statement> as Src on target.IDA = Src.IDA
WHEN MATCHED
//update
WHEN NOT MATCHED
//insert <------ Fails because obviously a new IDB is required
Also tried various approaches like a nested select that sends IDB on the OUTPUT but it fails because IDB is a PK.
Other kinds of merges also failed eg:
MERGE Table A with <cursor data set as a select statement>
...
MERGE Table A with Table B
WHEN NOT MATCHED
//insert on Table A
WHEN NOT MATCHED
// Update Table B
Does anyone have an idea on this? Essentially I think if we generalise the question would be:
Can I insert and return the PK in one statement that can be nested in other statements
Thanks in advance for any replies
George
If you have an autogenerated PK on TableB, you can use code similar to this. Otherwise, just change the INSERT into TableA to grab the PK from TableB first.