我有一个xml文档,其中包含Statement:
的详细信息<Statement>
<Id />
<Invoices>
<Invoice>
<Id />
<Date />
<AmountDue />
etc.
</Invoice>
<Invoice>
<Id />
<Date />
<AmountDue />
etc.
</Invoice>
<Invoice>
<Id />
<Date />
<AmountDue />
etc.
</Invoice>
</Invoices>
</Statement>
这适用于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,日期和金额 - 完美。
当我尝试提取所有发票详细信息时出现问题。我目前有七个交叉申请声明,我收到以下消息:
“查询处理器耗尽内部资源而无法使用 制定查询计划。这是一个罕见的事件,只有预期 非常复杂的查询或引用非常大的查询 表或分区的数量。请简化查询。如果你 相信您错误地收到了此消息,请联系客户 支持服务以获取更多信息。“
我想要做的是让一个交叉申请发票并缩小select语句中的确切字段,但除非我使用'。'我必须使语句返回单例,并且我没有获得所需的所有数据。
我已经做了一些关于在select语句中指定命名空间的研究,但是所有的例子都将命名空间设置为http地址而不是xml文档中的节点,我还没有得到任何回报方法
我正在寻找的结果是这样的,但有更多的发票明细:
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 ...
我应该从哪里离开?
编辑:我删除了一些不必要的信息。获取所有特定于发票的详细信息是我的目标。答案 0 :(得分: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
会将您的XML碎化为行,以便每行T.N
指向自己的Invoice节点。在该节点上只有一个Id
节点,因此获取指定单个Id[1]
的值。
您可以使用Id[1]
或(Id/text())[1]
,但后者会为您提供更有效的执行计划。