Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何使用SQL变量迭代XML节点_Sql Server_Xml_Sql Server 2008 - Fatal编程技术网

Sql server 如何使用SQL变量迭代XML节点

Sql server 如何使用SQL变量迭代XML节点,sql-server,xml,sql-server-2008,Sql Server,Xml,Sql Server 2008,我在SQL Server 2008中有以下XML: DECLARE @xml xml = '<Root> <Contacts> <Contact name="John Doe" type="REG" other="value" /> <Contact name="Jane Doe" type="REG" other=

我在SQL Server 2008中有以下XML:

DECLARE @xml xml = '<Root>
                      <Contacts>
                        <Contact name="John Doe" type="REG" other="value" />
                        <Contact name="Jane Doe" type="REG" other="value" />
                        <Contact name="Jennifer Doe" type="REG" other="value" />
                        <Contact name="Jane Doe" type="REG" other="value" />
                      </Contacts>
                    </Root>'
“做正确的事”,不管我在括号里加了什么值。如上所述,将第一个更改为[3],将第三个更改为[3],以此类推

我想改变所有这些,不管有多少。因此,我需要获得计数,然后使用变量对其进行迭代。获取计数很容易,但我无法使变量工作

瞧,这个用变量替换上面[1]的XML不起作用

DECLARE @i int = 1
SET @xml.modify('replace value of (/Root/Contacts/Contact)[sql:variable("@i")]/@type with "NEW"')
SELECT @xml
它给了我这个错误,它告诉我我做错了什么,但我无法通过摸索错误来找出我做错了什么:

Msg 2337,第16级,状态1,第14行
XQuery[modify()]:“replace”的目标最多只能是一个节点,找到“attribute(type,xdt:untypedAtomic)*”

当我即将点击“Post”时,我发现了一些引用,其中提到必须使用position()才能在节点索引上使用变量,但示例是一个查询,而不是modify。这也不行

DECLARE @i int = 1
SET @xml.modify('replace value of (/Root/Contacts/Contact)[position()=sql:variable("@i")]/@type with "NEW"')
SELECT @xml
毫无疑问,这很简单,但我在这里和其他地方搜索了如何使用
sql:variable
,我发现的几乎所有示例都将其用作替换中的值,而不是索引(“可能已经有答案的问题”也没有任何帮助。)我还尝试过在不同的地方使用额外的括号,等等,只是没能找到神奇的组合


要使上述设置与@I一起工作,我还缺少什么?

您自己的代码只需再处理一个
[1]
。函数
.modify()
无法解释
[sql:variable(…)]
。。。这可能是任何筛选器,甚至是具有多个结果的筛选器。。。因此,只需将此更改为:

DECLARE @xml xml = '<Root>
                      <Contacts>
                        <Contact name="John Doe" type="REG" other="value" />
                        <Contact name="Jane Doe" type="REG" other="value" />
                        <Contact name="Jennifer Doe" type="REG" other="value" />
                        <Contact name="Jane Doe" type="REG" other="value" />
                      </Contacts>
                    </Root>';
DECLARE @i int = 1
SET @xml.modify('replace value of (/Root/Contacts/Contact)[sql:variable("@i")][1]/@type with "NEW"')
SELECT @xml
另一种方法是FLWOR:

SELECT @xml.query('
for $r in /Root/Contacts
    return <Root><Contacts>
    {
        for $c in /Root/Contacts/Contact
           return <Contact name="{$c/@name}" type="NEW" other="{$c/@other}"/>
    }
    </Contacts></Root>
')
SELECT@xml.query('
对于/Root/Contacts中的$r
返回
{
对于$c in/Root/Contacts/Contact
返回
}
')

您自己的代码只需再使用一个
[1]
。函数
.modify()
无法解释
[sql:variable(…)]
。。。这可能是任何筛选器,甚至是具有多个结果的筛选器。。。因此,只需将此更改为:

DECLARE @xml xml = '<Root>
                      <Contacts>
                        <Contact name="John Doe" type="REG" other="value" />
                        <Contact name="Jane Doe" type="REG" other="value" />
                        <Contact name="Jennifer Doe" type="REG" other="value" />
                        <Contact name="Jane Doe" type="REG" other="value" />
                      </Contacts>
                    </Root>';
DECLARE @i int = 1
SET @xml.modify('replace value of (/Root/Contacts/Contact)[sql:variable("@i")][1]/@type with "NEW"')
SELECT @xml
另一种方法是FLWOR:

SELECT @xml.query('
for $r in /Root/Contacts
    return <Root><Contacts>
    {
        for $c in /Root/Contacts/Contact
           return <Contact name="{$c/@name}" type="NEW" other="{$c/@other}"/>
    }
    </Contacts></Root>
')
SELECT@xml.query('
对于/Root/Contacts中的$r
返回
{
对于$c in/Root/Contacts/Contact
返回
}
')

好吧,这很管用,但如果我明白它为什么管用,我会被责骂的。:)变量用作索引(在括号中)。为什么我需要另一个索引?(主要是修辞性的;它有效,所以我会使用它,我只是不理解它。)派生表会变得混乱;实际的XML要复杂得多,有很多父/子节点,比如Contacts。我只需要更改多父节点XML中一组节点的一个属性,因此我认为只对这些节点进行迭代是最简单的。谢谢@vr8ce,这并不难:方括号允许您放置
XQuery
-过滤器。例如,您可以筛选所有
联系人
-元素,如
/Root/Contacts/Contact[@name=“Jane Doe”]
。在您的示例中,这将返回两行。但文字数字是一个明确的位置。使用
.modifiy()
引擎必须确保这只会影响一个节点。换言之:在变量的位置找到所有元素,然后取第一个(对我们来说很有趣,但对引擎来说不是…)好吧,这是可行的,但如果我理解它为什么有效,我会被责骂的。:)变量用作索引(在括号中)。为什么我需要另一个索引?(主要是修辞性的;它有效,所以我会使用它,我只是不理解它。)派生表会变得混乱;实际的XML要复杂得多,有很多父/子节点,比如Contacts。我只需要更改多父节点XML中一组节点的一个属性,因此我认为只对这些节点进行迭代是最简单的。谢谢@vr8ce,这并不难:方括号允许您放置
XQuery
-过滤器。例如,您可以筛选所有
联系人
-元素,如
/Root/Contacts/Contact[@name=“Jane Doe”]
。在您的示例中,这将返回两行。但文字数字是一个明确的位置。使用
.modifiy()
引擎必须确保这只会影响一个节点。换句话说:在变量的位置找到所有元素,然后取第一个(对我们来说很有趣,但对引擎来说不是…)