I have a table with a complex primary key. Also I have a Service Broker service which receives XML message which basically looks like the following:
<TableName>
<CHANGED key1="1" key2="2" key3="3" timestamp="00:00:01"/>
<CHANGED key1="1" key2="2" key3="3" timestamp="00:00:02"/>
<CHANGED key1="1" key2="2" key3="3" timestamp="00:00:03"/>
</TableName>
My goal is to insert those values into a table.
I tried the following query:
INSERT INTO TableName (KEY1, KEY2, KEY3, TS)
SELECT
Tbl.Col.value('@*[1]', 'int'),
Tbl.Col.value('@*[2]', 'int'),
Tbl.Col.value('@*[3]', 'int'),
Tbl.Col.value('@*[4]', 'datetime')
FROM @MESSAGE.nodes('//CHANGED') Tbl(Col)
But in case when we have several records with the same complex key (key1, key2, key3) and different timestamp (value I need for my biz logic) this query fails with the following error message:
Violation of PRIMARY KEY constraint ‘TableName’. Cannot insert
duplicate key in object ‘dbo.TableName’. The duplicate key value is
(1, 2, 3).
Is there a way to insert only distinct values with the latest timestamp from that message?
Do a
group byon the keys and aggregate ontimestamp(min or max?).To be really safe you should use the attribute names instead of
position(). According to Limitations of the xml Data Type the order of attributes is not guaranteed.