1

複雑な主キーを持つテーブルがあります。また、基本的に次のような XML メッセージを受信する Service Broker サービスがあります。

  <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) です。

そのメッセージから最新のタイムスタンプを持つ個別の値のみを挿入する方法はありますか?

4

1 に答える 1

2

キーに対してaを実行し、 (最小または最大?)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()xmlデータ型の制限によると、属性の順序は保証されていません。

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

于 2012-04-13T11:46:03.797 に答える