【问题标题】:MSSQL XML max function returns nullMSSQL XML 最大函数返回 null
【发布时间】:2013-10-25 10:05:27
【问题描述】:

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

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

所以我想我没有正确使用max 函数,但我做错了什么?

【问题讨论】:

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


    【解决方案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

    【讨论】:

    • 您的解决方法确实有效,但它(不可避免地)很复杂,特别是因为我必须在 .NET 实体框架的一个语句中使用其中两个查询。当然,您的答案解决了问题 - 尽管我使用了另一种解决方法,我重组了 C# 代码以允许更简单的查询。 (现在我检查是否存在具有特定 Revision 属性值的 XML 节点。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 2021-03-31
    • 2016-01-30
    相关资源
    最近更新 更多