0

在我的交易表中,我有一个 XML 列,其中包含有关交易的一些附加信息,例如交易中的某些价格是如何计算的(针对发布方和卖方方)。由于计算算法可能会发生变化,因此可以多次计算交易。完整的计算历史保存在 XML 中。

现在我想要最近计算的算法的修订号。XML 结构如下所示:

<DataItems>
    <!-- ... more data here ... -->
    <CalculationHistory>
        <Seller Revision="3" Time="2013-10-22T10:00:18.6294944Z" Result="20">
            <Step Index="0" NodeId="c3e33dd5-25e0-4272-8b6f-f65fb2f0659b">bla</Step>
            <Step Index="1" NodeId="b76b0915-7527-4df4-8185-5a425e723491">bla</Step>
            <Step Index="2" NodeId="7e51947e-85ef-431f-8a21-9f4e30136805">bla</Step>
            <Step Index="3" NodeId="10212fe9-8378-463d-b35b-27225b3cf2a1">bla</Step>
        </Seller>
        <Seller Revision="4" Time="2013-10-22T14:54:53.974548Z" Result="20">
            <Step Index="0" NodeId="c3e33dd5-25e0-4272-8b6f-f65fb2f0659b">bla</Step>
            <Step Index="1" NodeId="b76b0915-7527-4df4-8185-5a425e723491">bla</Step>
            <Step Index="2" NodeId="7e51947e-85ef-431f-8a21-9f4e30136805">bla</Step>
            <Step Index="3" NodeId="10212fe9-8378-463d-b35b-27225b3cf2a1">bla</Step>
        </Seller>
        <Publisher Revision="7" Time="2013-10-22T14:54:53.9794031Z" Result="40">
            <Step Index="0" NodeId="2ce85808-903f-40b0-b8a9-c72e02d36d71">bla</Step>
            <Step Index="1" NodeId="50ca67cc-5df8-450d-06d9-72c224027406">bla</Step>
            <Step Index="2" NodeId="b2122e9f-c15b-4fa8-ce22-3dc73933d3d3">bla</Step>
        </Publisher>
    </CalculationHistory>
</DataItems>

所以我尝试的是选择最新的修订号作为这样的列:

SELECT XmlColumn.value('(/DataItems/CalculationHistory/Seller[@Time = max(/DataItems/CalculationHistory/Seller/@Time)]/@Revision)[1]', 'int') AS SellerRevision FROM Transactions

但这null每次都会返回。我发现问题是即使在这种情况下也会max()返回函数:null

SELECT XmlColumn.query('max(/DataItems/CalculationHistory/Seller/@Time)') FROM Transactions

...尽管替换maxdata返回正确的时间戳。

所以我想我没有max正确使用该功能,但我做错了什么?

4

1 回答 1

1

这很奇怪,max不适用于字符串属性/元素:

select (select cast('<A D="1"/>' as xml)).query('max(/A/@D)')
-- returns 1

select (select cast('<A D="a"/>' as xml)).query('max(/A/@D)')
-- returns nothing

一些解决方法可能是使用变量:

declare @Time nvarchar(max)

select @Time = max(T.C.value('@Time', 'nvarchar(max)'))
from @Data.nodes('DataItems/CalculationHistory/Seller') as T(C)

select @Data.value('(/DataItems/CalculationHistory/Seller[@Time=sql:variable("@Time")]/@Revision)[1]', 'int')

sql fiddle demo

我稍后会尝试检查是否可以在 SQL Server xpath 中对字符串使用 max

于 2013-10-25T14:45:36.743 回答