2012-04-13 24 views
1

私は複雑な主キーを持つテーブルを持っています。また、私は基本的に次のようなXMLメッセージを受信したService Brokerのサービスがあります。XMLからテーブルから別の値を挿入する

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

私の目標は、テーブルにそれらの値を挿入することです。

は、私は次のクエリを試してみました:

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) 

しかし、我々は(私は私のビズ・ロジックのために必要な値)と同じ複雑なキー(KEY1、KEY2、KEY3)と異なるタイムスタンプを持ついくつかのレコードを持っている場合は、このクエリは、次のエラーメッセージで失敗します。

PRIMARY KEY制約 'TableName'の違反。オブジェクト 'dbo.TableName'に 重複キーを挿入できません。重複キーの値は (1,2,3)です。

メッセージの最新のタイムスタンプで別個の値だけを挿入する方法はありますか?

答えて

2

キー上でgroup byを実行し、timestamp(最小または最大?)に集約します。

INSERT INTO TableName (KEY1, KEY2, KEY3, TS) 
SELECT key1, key2, key3, MIN(ts) 
FROM 
    (
    SELECT 
     Tbl.Col.value('@key1', 'int') AS key1, 
     Tbl.Col.value('@key2', 'int') AS key2, 
     Tbl.Col.value('@key3', 'int') AS key3, 
     Tbl.Col.value('@timestamp', 'datetime') as ts 
    FROM @MESSAGE.nodes('//CHANGED') Tbl(Col) 
) AS M 
GROUP BY key1, key2, key3 

あなたの代わりにposition()の属性名を使用する必要があり、本当に安全です。 Limitations of the xml Data Typeによれば、属性の順序は保証されていません。

XMLインスタンス内の属性の順序は保持されません。 xml型列に格納されたXMLインスタンスを照会すると、結果のXMLの 属性の順序が元のXML インスタンスと異なる場合があります。

+1

はい、これはまさに私が必要なものです!属性についてのあなたのコメントをありがとう、私はこれを考慮に入れます。 –

関連する問題