3

ステートメントの詳細を含むxmlドキュメントがあります。

<Statement>
<Id />

<Invoices>
    <Invoice>
        <Id />
        <Date />
        <AmountDue />
        etc.
    </Invoice>

    <Invoice>
        <Id />
        <Date />
        <AmountDue />
        etc.
    </Invoice>

    <Invoice>
        <Id />
        <Date />
        <AmountDue />
        etc.
    </Invoice>
</Invoices>

</Statement>

これは、ステートメント固有の詳細に対して正常に機能します。

SET @statementId = @xml.value('(Id)[1]', 'UNIQUEIDENTIFIER');

ただし、シングルトンが必要であり、最初の値のみを返します。最初の値だけでなく、請求書のすべての値が必要なので、シングルトンは機能しません。

次のようなクロスアプライステートメントを使用して情報を取得できます。

SELECT 
@statementId AS STATEMENT_ID
Id.value('.', 'uniqueidentifier') AS INVOICE_ID
Date.value('.', 'smalldatetime') AS INVOICE_DATE
Due.value('.', 'decimal') AS INVOICE_AMOUNT_DUE

FROM @xml.nodes('Statement') A(S)
cross apply S.nodes('Invoices/Invoice') B(InvoiceD)
cross apply InvoiceD.nodes('Id') C(Id)
cross apply InvoiceD.nodes('Date') D(Date)
cross apply InvoiceD.nodes('AmountDue') E(Due)

これにより、ステートメントの各請求書からID、日付、および金額が返されます-完璧です。

すべての請求書の詳細を抽出しようとすると、問題が発生します。現在、7つの相互適用ステートメントがあり、次のメッセージが表示されます。

「クエリプロセッサが内部リソースを使い果たし、クエリプランを作成できませんでした。これはまれなイベントであり、非常に複雑なクエリ、または非常に多くのテーブルやパーティションを参照するクエリでのみ発生します。クエリを簡略化してください。このメッセージを誤って受け取った場合は、カスタマーサポートサービスに詳細をお問い合わせください。」

私がやりたいのは、請求書に1つのクロスを適用し、selectステートメントの正確なフィールドを絞り込むことですが、「。」を使用しない限り、ステートメントがシングルトンを返すようにする必要がありますが、必要なすべてのデータを取得できません。

selectステートメント内で名前空間を指定することについていくつかの調査を行いましたが、すべての例で名前空間がxmlドキュメントのノードではなくhttpアドレスに設定されており、このアプローチを使用してまだ何も返されていません。

私が探している結果は次のようなものですが、請求書の詳細がさらに含まれています。

STATEMENT_ID      INVOICE_ID      INVOICE_DATE      INVOICE_AMOUNT_DUE     ...
Statement-1-Id    Invoice-1-Id    Invoice-1-Date    Invoice-1-AmountDue    ...
Statement-1-Id    Invoice-2-Id    Invoice-2-Date    Invoice-2-AmountDue    ...
Statement-1-Id    Invoice-3-Id    Invoice-3-Date    Invoice-3-AmountDue    ...

ここからどこへ行けばいいの?

編集:私はいくつかの不要な情報を削除しました。ここでの私の目標は、請求書固有の詳細をすべて取得することです。

4

1 に答える 1

4
select @XML.value('(Statement/Id/text())[1]', 'uniqueidentifier') as StatementId, 
       T.N.value('(Id/text())[1]', 'uniqueidentifier') as InvoiceId,
       T.N.value('(Date/text())[1]', 'smalldatetime') as InvoiceDate,
       T.N.value('(AmountDue/text())[1]', 'decimal') as AmountDue
from @XML.nodes('/Statement/Invoices/Invoice') as T(N)

.nodes各行T.Nが独自の Invoice ノードを指すように、XML を行に分割します。そのノードにはノードが 1 つしかないIdため、シングルトンを指定して値をフェッチすると機能しId[1]ます。

Id[1]orを使用できます(Id/text())[1]が、後者を使用すると、より効率的な実行計画が得られます。

于 2012-09-26T20:15:09.703 に答える