标签: xquery

使用 XPath/XQuery 连接同一 XML 元素的所有值

我有一个这样的 XML 值:

<R>
  <I>A</I>
  <I>B</I>
  <I>C</I>
  ...
</R>
Run Code Online (Sandbox Code Playgroud)

我想连接所有的I值并返回它们作为单个字符串:ABC...

现在我知道我可以分解 XML,将结果聚合回无节点 XML,然后应用于.values('text()[1]', ...)结果:

SELECT
  (
    SELECT
      n.n.value('text()[1]', 'varchar(50)') AS [text()]
    FROM
      @MyXml.nodes('/R/I') AS n (n)
    FOR XML
      PATH (''),
      TYPE
  ).value('text()[1]', 'varchar(50)')
;
Run Code Online (Sandbox Code Playgroud)

但是,我想仅使用 XPath/XQuery 方法来完成所有这些工作,如下所示:

SELECT @MyXml. ? ( ? );
Run Code Online (Sandbox Code Playgroud)

有这样的方法吗?

我在这个方向寻找解决方案的原因是因为我的实际 XML 也包含其他元素,例如:

SELECT
  (
    SELECT
      n.n.value('text()[1]', 'varchar(50)') AS [text()]
    FROM
      @MyXml.nodes('/R/I') AS n (n)
    FOR XML
      PATH (''),
      TYPE
  ).value('text()[1]', 'varchar(50)')
;
Run Code Online (Sandbox Code Playgroud)

而且我希望能够将I值提取为单个字符串,并将J值提取为单个字符串,而不必为每个值使用笨拙的脚本。

xml sql-server xquery sql-server-2014

14
推荐指数
2
解决办法
4111
查看次数

用 XQuery 替换 SQL Server 中强类型 xml 元素的值

给定一个在 XML 模式集合中定义的元素,如下所示:

<xsd:element name="xid">
    <xsd:simpleType>
        <xsd:restriction base="xsd:string">
            <xsd:maxLength value="32" />
        </xsd:restriction>
    </xsd:simpleType>
</xsd:element>
Run Code Online (Sandbox Code Playgroud)

您将如何使用 XQuery 更新元素?

该元素位于架构集合的ns命名空间中。我一直在尝试更新以下查询的元素:

update cm.item
   set data.modify(
    'declare namespace ns="http://www.anon.com"; 
     replace value of (/ns:*/ns:xid)[1] with "X00011793" cast as element(ns{http://www.anon.com}:xid,#anonymous) ?') 
 where id = 11793
Run Code Online (Sandbox Code Playgroud)

但这会产生以下错误:

消息 9301,级别 16,状态 1,第 2 行 XQuery [cm.item.data.modify()]:在此版本的服务器中,“cast as”不可用。请使用“演员为?” 句法。

如果我完全删除演员表并使用此查询:

update cm.item
   set data.modify(
    'declare namespace ns="http://www.anon.com"; 
     replace value of (/ns:*/ns:xid)[1] with "X00011793"') 
 where id = 11793
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

消息 2247,级别 16,状态 1,第 2 行 XQuery [cm.item.data.modify()]:该值的类型为“xs:string”,它不是预期类型“<anonymous>”的子类型。

如果我发出这个查询: …

xml sql-server sql-server-2008-r2 xquery

11
推荐指数
1
解决办法
1934
查看次数

修改 XML:将属性转换为元素

我有一XML列包含具有类似结构的数据:

<Root>
    <Elements>
        <Element Code="1" Value="aaa"></Element>
        <Element Code="2" Value="bbb"></Element>
        <Element Code="3" Value="ccc"></Element>
    </Elements>
</Root>
Run Code Online (Sandbox Code Playgroud)

如何使用 SQL Server 修改数据以将每个Value属性更改为元素?

<Root>
    <Elements>
        <Element Code="1">
            <Value>aaa</Value>
        </Element>
        <Element Code="2">
            <Value>bbb</Value>
        </Element>
        <Element Code="3">
            <Value>ccc</Value>
        </Element>
    </Elements>
</Root>
Run Code Online (Sandbox Code Playgroud)

更新:

我的 XML 看起来更像这样:

<Root attr1="val1" attr2="val2">
    <Elements>
        <Element Code="1" Value="aaa" ExtraData="extra" />
        <Element Code="2" Value="bbb" ExtraData="extra" />
        <Element Code="3" Value="ccc" ExtraData="extra" />
        <Element Code="4" Value="" ExtraData="extra" />
        <Element Code="5" ExtraData="extra" />
    </Elements>
    <ExtraData>
       <!-- Some XML is here -->
    </ExtraData>
</Root> …
Run Code Online (Sandbox Code Playgroud)

xml sql-server xquery

11
推荐指数
2
解决办法
3290
查看次数

返回属性不包含特定字符的 xml 序列

考虑以下简单的 XML:

<xml>
  <customer name="Max">
    <email address="me@you.com" />
  </customer>
  <customer name="Erik">
    <email address="erik@your-mom.com" />
  </customer>
  <customer name="Brent">
    <email address="brentcom" />
  </customer>
</xml>
Run Code Online (Sandbox Code Playgroud)

我想要得到的名单<Customer>,其中序列address中的属性<email>项并没有包含@

所以,我希望输出看起来像:

<customer name="Brent">
  <email address="brentcom" />
</customer>
Run Code Online (Sandbox Code Playgroud)

麦克维

DECLARE @x XML = '<xml>
<customer name="Max"><email address="me@you.com" /></customer>
<customer name="Erik"><email address="erik@your-mom.com" /></customer>
<customer name="Brent"><email address="brentcom" /></customer>
</xml>';
Run Code Online (Sandbox Code Playgroud)

这个查询:

SELECT WithValidEmail = @x.query('/xml/customer/email[contains(@address, "@")]')
    , WithInvalidEmail = @x.query('/xml/customer/email[contains(@address, "@")] = False');
Run Code Online (Sandbox Code Playgroud)

返回:

????????????????????????????????????????????????????????????
?            WithValidEmail             ? WithInvalidEmail ? …
Run Code Online (Sandbox Code Playgroud)

xml sql-server xquery

10
推荐指数
1
解决办法
2706
查看次数

使用 XQuery 过滤掉一些孩子,但保留父母

SET NOCOUNT ON;
DECLARE @xml AS Xml = '<a><b>bbb</b><c>ccc</c><d>ddd</d></a>';
SELECT @xml;
SELECT @xml.query('/a/*[self::b or self::c]');
SET @xml.modify('delete /a/d');
SELECT @xml;
Run Code Online (Sandbox Code Playgroud)

给出以下结果集

原来的:

<a><b>bbb</b><c>ccc</c><d>ddd</d></a>
Run Code Online (Sandbox Code Playgroud)

过滤以排除非 (b|c) - 但缺少父母:

<b>bbb</b><c>ccc</c>
Run Code Online (Sandbox Code Playgroud)

我想要什么(可用于删除步骤,但不可用于 .query):

<a><b>bbb</b><c>ccc</c></a>
Run Code Online (Sandbox Code Playgroud)

是否可以在 XQuery 中保留父项?

sql-server xquery

9
推荐指数
1
解决办法
514
查看次数

XML 列的 IN 和 NOT IN

我有一个带有 xml 列的表。XML类似于

<Root>
  <Row>
    <user>abc</user>
    <Rowid>1</Rowid>
  </Row>
  <Row>
    <user>vf</user>
    <Rowid>2</Rowid>
  </Row>
  <Row>
    <user>ert</user>
    <Rowid>3</Rowid>
  </Row>
  <Maxrowid>3</Maxrowid>
</Root>
Run Code Online (Sandbox Code Playgroud)

现在下面的查询返回 sl_no 列和包含 xml 列的行的 myxmlcolumn 在节点 'user'() 中具有值 'abc' 或 'xyz'。下面的查询我使用类似于 sql 的 IN 选项。

SELECT
    [mytable].[Sl_no],
    [mytable].[myxmlcolumn]
    FROM [mydb].dbo.[mytable]
    WHERE
        [myxmlcolumn].exist('for $x in /Root/Row where (($x/user[fn:upper-case(.)=(''ABC'',''XYZ'')])) return $x') > 0
Run Code Online (Sandbox Code Playgroud)

我想要类似的查询,它与 sql 'NOT IN' 做同样的工作。在我的情况下,我希望在 xml 列中的节点“user”() 中没有值“abc”或“xyz”的行。所以请帮我解决这个问题。

xml sql-server sql-server-2008-r2 xquery

8
推荐指数
1
解决办法
326
查看次数

从 XML 返回可变数量的属性作为逗号分隔值

过度延伸

在阻塞进程报告和死锁 XML 的 SQL Server 扩展事件中,可以获取多个 SQL 句柄值以识别引发事件中涉及的查询。

由于可能涉及 1 个或多个 SQL 句柄,因此可靠地查询 XML 以检索所有这些句柄可能会很困难,并且还会使更简单的 XQuery 不正确,因为它仅检索第一个存储的值。

sqlhandle = bd.value('(process/executionStack/frame/@sqlhandle)[1]', 'varchar(130)'),
Run Code Online (Sandbox Code Playgroud)

用于说明的示例 XML 片段如下所示:

<executionStack>
      <frame line="1" stmtend="108" sqlhandle="0x020000008d18260040e407ba48fc247b0cb6121c21c2cf2b0000000000000000000000000000000000000000" />
      <frame line="1" stmtend="108" sqlhandle="0x02000000dd847b18dcaa4a09a89f56595186fcf91da8a7f70000000000000000000000000000000000000000" />
</executionStack>
Run Code Online (Sandbox Code Playgroud)

此 SQL Fiddle提供了更完整的示例。

我已经做到了这一点:

SELECT 
    sql_handle = 
        @x.query('for $s in //executionStack/frame return $s');  
Run Code Online (Sandbox Code Playgroud)

但这并没有得到我所追求的。扩展该查询以使用该@sqlhandle属性会引发错误:

SELECT 
    sql_handle = 
        @x.query('for $s in //executionStack/frame/@sqlhandle return $s');  
Run Code Online (Sandbox Code Playgroud)

消息 2396,级别 16,状态 1,第 60 行 XQuery [query()]:属性不得出现在元素外部

我怎样才能像这样查询 XML 以将所有列出的 SQL 句柄作为逗号分隔列表返回?

xml sql-server extended-events xquery

8
推荐指数
2
解决办法
696
查看次数

XQuery 不更新 XML 数据

我正在尝试运行脚本来更新 XML 列:

UPDATE DataImpTable
SET serviceData.modify('replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData/text())[1] with "9876"')
WHERE identifier=5
Run Code Online (Sandbox Code Playgroud)
UPDATE DataImpTable
SET serviceData.modify('replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData/text())[1] with "9876"')
WHERE identifier=5
Run Code Online (Sandbox Code Playgroud)

将 的值更改ControlData为 9876,但该值在 XML 中似乎没有更改/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData

它与类型化和非类型化 XML 有什么关系?

xml sql-server update xquery

7
推荐指数
2
解决办法
193
查看次数

SQL Server / XML.query() 导致大量内存授予

以下(在我的系统上,在 SQL Server 2016 和 2019 std 上测试)产生大量内存授予请求(3327 MB)

declare @wibble xml = '<wibble><wobble>1</wobble></wibble>'

select @wibble.query('//wobble[1]')
Run Code Online (Sandbox Code Playgroud)

我可以做些什么来减少补助金?

https://www.brentozar.com/pastetheplan/?id=HkezxS8-K

xml sql-server xquery memory-grant

7
推荐指数
1
解决办法
591
查看次数

如何将 XML 数组拆分为单独的行(同时保持一致性)

我正在处理这个确切的堆栈交换部分的数据库转储。在我处理它的过程中,我遇到了一个我目前无法解决的问题。

在 XML 文件 Posts.xml 中,内容如下所示

在此处输入图片说明

当然有多行,但这就是一个的样子。转储中已经提供了一个 Tags.xml 文件,这使得该图片中的“Tags”属性实际上应该是它的单独表(多对多)变得更加明显。

所以现在我正试图找出一种如何提取标签的方法。这是我尝试做的:

CREATE TABLE #TestingIdea (
Id int PRIMARY KEY IDENTITY (1,1),
PostId int NULL,
Tag nvarchar (MAX) NULL
)
GO
Run Code Online (Sandbox Code Playgroud)

? 我创建的表来测试我的代码。我已经用标签和 PostIds 填充了它

SELECT  T1.PostId,
        S.SplitTag
FROM (
    SELECT  T.PostId, 
            cast('<X>'+ REPLACE(T.Tag,'>','</X><X>') + '</X>' as XML) AS NewTag
    FROM #TestingIdea AS T
    ) AS T1
CROSS APPLY (
    SELECT tData.value('.','nvarchar(30)') SplitTag
    FROM T1.NewTag.nodes('X') AS T(tData)
    ) AS S
GO
Run Code Online (Sandbox Code Playgroud)

然而此代码返回此错误

XML parsing: line 1, character 37, illegal qualified name character …
Run Code Online (Sandbox Code Playgroud)

xml sql-server xquery string-splitting sql-server-2017

6
推荐指数
1
解决办法
2431
查看次数