MSSQL XML max函数返回null

时间:2013-10-25 10:05:27

标签: sql xml xpath sql-server-2008-r2 sqlxml

在我的交易表中,我有一个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

...虽然用max替换data会返回正确的时间戳。

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

1 个答案:

答案 0 :(得分: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 on strings