我有一个这样的 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 模式集合中定义的元素,如下所示:
<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列包含具有类似结构的数据:
<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:
<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) 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 中保留父项?
我有一个带有 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 句柄值以识别引发事件中涉及的查询。
由于可能涉及 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 列:
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 有什么关系?
以下(在我的系统上,在 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)
我可以做些什么来减少补助金?
我正在处理这个确切的堆栈交换部分的数据库转储。在我处理它的过程中,我遇到了一个我目前无法解决的问题。
在 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)