Reputation: 5
I have a table that I am trying to insert multiple records into using a select statement.
The ID field is an INT and not autoincremented but I do need to increment in in the INSERT.
The table belongs to a third party product we use for our ERP so I cannot change the property of the ID.
The insert is supposed to create a record in the EXT01100 table for each line item on a particular sales order.
Here is the code I am using:
INSERT INTO EXT01100 (Extender_Record_ID, Extender_Window_ID, Extender_Key_Values_1 , Extender_Key_Values_2, Extender_Key_Values_3)
SELECT (SELECT MAX(EXTENDER_RECORD_ID) + 1 FROM EXT01100), 'ECO_FEE_DIGIT', SOL.LNITMSEQ, SOL.SOPNUMBE, SOL.SOPTYPE
FROM SOP10200 SOL WITH(NOLOCK)
WHERE SOL.SOPTYPE = @InTYPE AND SOL.SOPNUMBE = @INNUMBE AND SOL.LNITMSEQ <> 0
This works on a single line order, but multiple line orders will produce a Primary Key duplicate error so I don't think I can use (SELECT MAX(EXTENDER_RECORD_ID) + 1 FROM EXT01100)
in this case.
This is in SQL server.
Any help is greatly appreciated!
Upvotes: 0
Views: 110
Reputation: 32687
Seconding a recommendation from the comments above, we use Sequences in our production system with no problem. Here's how it looks:
create sequence SQ_Extender_Record_ID
minvalue 1
start with 1
cache 100;
INSERT INTO EXT01100 (Extender_Record_ID, Extender_Window_ID, Extender_Key_Values_1 , Extender_Key_Values_2, Extender_Key_Values_3)
SELECT (next value for SQ_Extender_Record_ID), 'ECO_FEE_DIGIT', SOL.LNITMSEQ, SOL.SOPNUMBE, SOL.SOPTYPE
FROM SOP10200 SOL
WHERE SOL.SOPTYPE = @InTYPE AND SOL.SOPNUMBE = @INNUMBE AND SOL.LNITMSEQ <> 0
Obviously, adjust the min/start values as appropriate for your situation.
If you want, you could add a default constraint to the table/column with this:
alter table EXT01100 add constraint DF_EXT01100__Extender_Record_ID
default (next value for SQ_Extender_Record_ID)
for Extender_Record_ID
You mention that this is in a database whose schema you don't control, so that may not be an option; I mention it for the sake of completeness.
Upvotes: 1
Reputation: 27202
You can use row_number
to ensure each row has a unique ID, and you need to take an exclusive lock on your main sequence table, and you need to remove your nolock
.
INSERT INTO EXT01100 (Extender_Record_ID, Extender_Window_ID, Extender_Key_Values_1 , Extender_Key_Values_2, Extender_Key_Values_3)
SELECT (SELECT MAX(EXTENDER_RECORD_ID) FROM EXT01100 WITH (TABLOCKX)) + ROW_NUMBER() OVER (ORDER BY SOL.LNITMSEQ)
, 'ECO_FEE_DIGIT', SOL.LNITMSEQ, SOL.SOPNUMBE, SOL.SOPTYPE
FROM SOP10200 SOL
WHERE SOL.SOPTYPE = @InTYPE AND SOL.SOPNUMBE = @INNUMBE AND SOL.LNITMSEQ <> 0;
Upvotes: 3