2

SQL Server (2012) の既存の xml インスタンス内に xml ノードを動的に挿入できるかどうかについてのドキュメントを見つけることができませんでした。条件値を挿入または置換できることは知っていますが、挿入の場所をいくつかの条件に基づいて動的に実行できるかどうかについてのドキュメントはないようです。たとえば、次の XML-DML 呼び出しがあるとします。

SET @xml.modify('insert <SecondaryContact><Name>{ sql:variable("@contactName") }</Name>
                    <Phone>{ sql:variable("@contactPhone") }</Phone>
                    <Email>{ sql:variable("@contactEmail") }</Email></SecondaryContact>
                    after (/Project/PrimaryContact)[1]');

キーワードの後に​​リストされているノードafterが条件付きである変更は有効な構文でしょうか? 以下は、私が言及しているものの例です。

SET @xml.modify('insert <TechnicalContact><Name>{ sql:variable("@contactName") }</Name>
                    <Phone>{ sql:variable("@contactPhone") }</Phone>
                    <Email>{ sql:variable("@contactEmail") }</Email></TechnicalContact>
                    after (
                        if(count(/Project/SecondaryContact) = 0)
                        then (/Project/PrimaryContact)[1]
                        else (/Project/SecondaryContact)(1)
                    )');

IF..ELSEXML DML ステートメントの外側にステートメントを持つ場所を動的に選択する唯一の方法ですか、それとも私の例の XML-DML は有効ですか?

XML の例を編集します。

<root>
    ...
    <PrimaryContact Id="1234">
        <Name>John Doe</Name>
        <Phone>555-555-5555</Phone>
        <Email>somewhere@test.com</Email>
    </PrimaryContact>
    <SecondaryContact Id="1236">   <--OPTIONAL
        <Name>John Doe1</Name>
        <Phone>555-555-5556</Phone>
        <Email>somewhere1@test.com</Email>
    </SecondaryContact>
    <TechnicalContact Id="2234"> <--OPTIONAL
        <Name>John Doe2</Name>
        <Phone>555-555-5255</Phone>
        <Email>somewhere3@test.com</Email>
    </TechnicalContact>
    ...
</root>

構造が理想的ではないことは承知しています。である必要があります<Contacts><Contact Type="PRIMARY" Id="1234">...</Contact>...</Contacts>が、DML ステートメント内で動的な挿入場所が可能かどうかを確認したかったのです。この質問では、1 回限りの更新であるため、カーソルの使用は問題ありません。

4

3 に答える 3

4

この提案は、 の後ではなく、ドキュメントの後半に来る方の後に挿入されるため、まったく同じではありませんがSecondaryContact、あなたの場合、これは同じことだと思います:

SET @xml.modify('insert 
    <TechnicalContact><Name>{ sql:variable("@contactName") }</Name>
    <Phone>{ sql:variable("@contactPhone") }</Phone>
    <Email>{ sql:variable("@contactEmail") }</Email></TechnicalContact>

    after (/Project/*[
        local-name(.) = "SecondaryContact" 
        or local-name(.) = "PrimaryContact" 
    ])[last()]
');

または:

if @xml.value('count(/Project/SecondaryContact)', 'int') = 0
begin
  SET @xml.modify('insert <TechnicalContact><Name>{ sql:variable("@contactName") }</Name>
                <Phone>{ sql:variable("@contactPhone") }</Phone>
                <Email>{ sql:variable("@contactEmail") }</Email></TechnicalContact>
                after (/Project/PrimaryContact)[1]
                ');
end else begin
  SET @xml.modify('insert <TechnicalContact><Name>{ sql:variable("@contactName") }</Name>
                <Phone>{ sql:variable("@contactPhone") }</Phone>
                <Email>{ sql:variable("@contactEmail") }</Email></TechnicalContact>
                after (/Project/SecondaryContact)[1]
                ');
end
于 2016-11-04T15:12:23.547 に答える
1

のシーケンスをその順序で作成し、最初の出現の後にノードを追加できます 。SecondaryContactPrimaryContact

insert 
  <TechnicalContact>
    <Name>{ sql:variable("@contactName") }</Name>
    <Phone>{ sql:variable("@contactPhone") }</Phone>
    <Email>{ sql:variable("@contactEmail") }</Email>
  </TechnicalContact>
after (
      /Project/SecondaryContact,
      /Project/PrimaryContact
      )[1]
于 2016-11-04T18:43:15.247 に答える