【问题标题】:XQuery / SQL Server iterative replace statementXQuery / SQL Server 迭代替换语句
【发布时间】:2014-06-04 14:13:46
【问题描述】:

我的问题是如何将迭代循环放入使用 XQuery 查找和更改节点值的 SQL Server 8 SQL 过程中。

我有一个 SQL Server 数据库表,其中包含一个名为 Data 的字段,其中包含 XML 数据,如下所示:-

<ContentTree xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://mynamespace">
    <ContentObject>
        <Id>164</Id>
        <Order>A</Order>
        <Catalogue>1</Catalogue>
    </ContentObject>
    <ContentObject>
        <Id>165</Id>
        <Order>A</Order>
        <Catalogue>1</Catalogue>
    </ContentObject>
    <ContentObject>
        <Id>166</Id>
        <Order>B</Order>
        <Catalogue>2</Catalogue>
    </ContentObject>
    <ContentObject>
        <Id>166</Id>
        <Order>B</Order>
        <Catalogue>2</Catalogue>
    </ContentObject>
</ContentTree>

我希望能够遍历所有 ContentObjects 并且 Order 值为 A,将 Catalog 值更改为 3。

我可以通过以下方式一次更改一个实例的值:-

UPDATE [Database Table]
SET Data.modify('declare namespace c="http://mynamespace";
replace value of (//c:ContentObject[c:Order = "A"]/c:Catalogue/text())[1] with ("3")')
WHERE DatabaseRecordId = '5'

但我希望能够将其置于一个循环中,并通过一个程序进行所有更改 - 这可能吗?

【问题讨论】:

    标签: sql sql-server xml xquery-sql


    【解决方案1】:

    根据Mikael Eriksson's answer,您可以遍历节点并为每个节点调用 modify():

    DECLARE @xml XML = 
        '<ContentTree xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://mynamespace">
            <ContentObject>
                <Id>164</Id>
                <Order>A</Order>
                <Catalogue>1</Catalogue>
            </ContentObject>
            <ContentObject>
                <Id>165</Id>
                <Order>A</Order>
                <Catalogue>1</Catalogue>
            </ContentObject>
            <ContentObject>
                <Id>166</Id>
                <Order>B</Order>
                <Catalogue>2</Catalogue>
            </ContentObject>
            <ContentObject>
                <Id>166</Id>
                <Order>B</Order>
                <Catalogue>2</Catalogue>
            </ContentObject>
        </ContentTree>'
    

    以下代码可以很容易地合并到存储过程中:

    DECLARE @counter INT = (
        SELECT @xml.value('declare namespace c="http://mynamespace";
            count(//c:ContentObject[c:Order = "A"])', 'INT')
    )
    
    WHILE @counter > 0
    BEGIN
    
        SET @xml.modify(
            'declare namespace c="http://mynamespace";
            replace value of (
                (//c:ContentObject[c:Order = "A"])[sql:variable("@counter")]
                /c:Catalogue/text())[1]
            with ("3")')
    
        SET @counter -= 1
    END
    
    SELECT @xml
    

    【讨论】:

    • 对不起,当时错过了这个答案。我最终通过计算所有订单、循环并更改 if = A 来完成我的项目,但这会更有效率。
    猜你喜欢
    • 2015-02-14
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多