我已经遍及整个网络(包括SO,但我可能会错过它)寻找一种方法,可以将节点插入到包含在变量中的现有XML中,而无需先在变量中创建XML作为节点的字符串想要插入并使用“ set @ XMLVariable01.modify('insert sql:variable(” @ XMLVariable02“)as ...”。
从下面的示例中,我想得到最终结果:
<P xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<L01>
<A xsi:nil="true" />
<B xsi:nil="true" />
<C xsi:nil="true" />
</L01>
<L02>
<A>2</A>
<B xsi:nil="true" />
<C>x</C>
</L02>
</P>
示例:
declare
@P xml;
declare
@A varchar,
@B varchar,
@C varchar;
select
@P = (
select
@A as [A],
@B as [B],
@C as [C]
for xml path(N'L01'), root('P'), type, elements xsinil
);
select @P; --Initial result
select
@A = '2',
@B = NULL,
@C = 'x';
--select @P = ...?
select @P; --Final result
我做了以下事情:
select
@P = (
select (
select
v.query('.')
from @P.nodes('P/L01') as t (v)),
(
select
@A as [A],
@B as [B],
@C as [C]
for xml path(N'L02'), type, elements xsinil
)
for xml path(N'P'), type, elements xsinil
);
哪一个接近,但我不想在XML的开头/顶行以外的任何位置使用“ xmlns:xsi =“ http://www.w3.org/2001/XMLSchema-instance”“:< / p>
<P xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<L01>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
<B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
<C xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
</L01>
<L02 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<A>2</A>
<B xsi:nil="true" />
<C>x</C>
</L02>
</P>
编辑(2018Dec14〜1343): 基于Schnugo的有用见解(是的,我需要/希望使用NULL值来记录所指示的元素,但未收到任何值。此外,我很抱歉,但我无法完全掌握所有内容1-5中提出的建议),我提出了以下建议:
select
@P = (
select
cast(replace(replace(cast(([XML].[Value]) as nvarchar(max)), cjR.Old01, cjR.New01), cjR.Old02, cjR.New02) as xml)
from (
select (
select
v.query('.')
from @P.nodes(N'P/L01') as t (v)),
(
select
@A as [A],
@B as [B],
@C as [C]
for xml path(N'L02'), type, elements xsinil
)
for xml path(N'P'), type, elements xsinil
) as [XML] ([Value])
cross join (
select
Value02 as Old01,
N'' as New01,
quotename(Value01, N'<>') as Old02,
quotename(Value01 + Value02, N'<>') as New02
from (
select
N'P',
N' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
) as R (Value01, Value02)
) as cjR
);
看起来像是一种骇人听闻的方式来产生应该如此简单的操作,但显然并非如此。我欢迎任何进一步的建议来改善这一点。
答案 0 :(得分:0)
您在这里遇到了SQL Server XML支持的各种缺陷...
使用嵌套XML,便没有其他方法可以使用子查询。但是子查询中的重复命名空间是一个非常烦人的问题。生成的XML完全可以,但是重复的名称空间声明确实会极大地膨胀您的XML。讨论了几个世纪(并寻求更好的解决方案)。有十多年的Connect-Ticket,获得了很多票。但这与Connect一起消失了。
您真的需要NULL
值来与xsi:nil
一起炫耀吗?默认是省略它们...
很多时候您会看到丑陋的解决方法
它们全部使用CAST
到NVARCHAR(MAX)
,使用字符串方法(STUFF
,SUBSTRING
,...)操纵名称空间,并在结束。
REPLACE
)纠正此问题(look at this answer)xsi:nil
来强制执行NULL
值,以免被忽略。更糟的是...您可以在创建XML的同时创建XML,然后使用字符串方法来丢弃错误的声明。FOR XML EXPLICIT
。这是一种奇怪且难以学习的格式。但这是我知道的唯一一种以所需的方式正确设置名称空间的方法。对不起,但这正是XML SQL-Server无法轻松构建的类型...
如果您需要有关所提供选项之一的帮助,则可以在此问题上先提出一个具体问题。