从 SQL Server 中的 XML 选择空值
我正在尝试从具有 null 作为属性之一的 XML 中进行选择。它没有返回 null,而是返回 0。我做错了什么?
请参阅下面的代码来复制:
declare @a xml
select @a = '<TestSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instace">
<Element>
<Property1>1</Property1>
<Property2>1</Property2>
</Element>
<Element>
<Property1 xsi:nil="true" />
<Property2>2</Property2>
</Element>
<Element>
<Property1>3</Property1>
<Property2>3</Property2>
</Element>
</TestSet>'
select ParamValues.TaskChainerTask.query('Property1').value('.','int') as Property1,
ParamValues.TaskChainerTask.query('Property2').value('.','int') as Property2
from @a.nodes('(/TestSet/Element)') as ParamValues(TaskChainerTask)
返回:
Property1 Property2
1 1
0 2
3 3
这将返回相同的内容:
declare @a xml
select @a = '<TestSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instace">
<Element>
<Property1>1</Property1>
<Property2>1</Property2>
</Element>
<Element>
<Property1 xsi:nil="true" />
<Property2>2</Property2>
</Element>
<Element>
<Property1>3</Property1>
<Property2>3</Property2>
</Element>
</TestSet>'
select ParamValues.TaskChainerTask.query('Property1').value('.','int') as Property1,
ParamValues.TaskChainerTask.query('Property2').value('.','int') as Property2
from @a.nodes('(/TestSet/Element)') as ParamValues(TaskChainerTask)
提前致谢。
I'm trying to select from XML that has a null as one of the attributes. Instead of returning a null, it returns a 0. What am I doing wrong?
See code below to replicate:
declare @a xml
select @a = '<TestSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instace">
<Element>
<Property1>1</Property1>
<Property2>1</Property2>
</Element>
<Element>
<Property1 xsi:nil="true" />
<Property2>2</Property2>
</Element>
<Element>
<Property1>3</Property1>
<Property2>3</Property2>
</Element>
</TestSet>'
select ParamValues.TaskChainerTask.query('Property1').value('.','int') as Property1,
ParamValues.TaskChainerTask.query('Property2').value('.','int') as Property2
from @a.nodes('(/TestSet/Element)') as ParamValues(TaskChainerTask)
returns:
Property1 Property2
1 1
0 2
3 3
This returns the same thing:
declare @a xml
select @a = '<TestSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instace">
<Element>
<Property1>1</Property1>
<Property2>1</Property2>
</Element>
<Element>
<Property1 xsi:nil="true" />
<Property2>2</Property2>
</Element>
<Element>
<Property1>3</Property1>
<Property2>3</Property2>
</Element>
</TestSet>'
select ParamValues.TaskChainerTask.query('Property1').value('.','int') as Property1,
ParamValues.TaskChainerTask.query('Property2').value('.','int') as Property2
from @a.nodes('(/TestSet/Element)') as ParamValues(TaskChainerTask)
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
http://go4answers.webhost4life.com/Example/include -null-columns-empty-elements-125474.aspx
这将选择 null。顺便说一句,作者代码有一个拼写错误,
实例被错误地拼写为 instace
作者代码的工作版本
http://go4answers.webhost4life.com/Example/including-null-columns-empty-elements-125474.aspx
This will select null. By the way author code has a typo
instance is misspelled as instace
Working version of author code
我想如果你使用 number() 函数,你会得到预期的 null 。但这仅适用于数字类型:
I think if you use the number() function, you'll get null as expected. This only works for number types though:
因为您将字段设置为 INT,所以会遇到 xsi:nil="true" 字段和值 0 最终都为 0 作为 INT Is 0 的默认值的问题。
您可以先转换为 VARCHAR 以检测空string ('') 包含 xsi:nil="true" 的字符串字段生成,然后将结果转换为 INT。
这个 SELECT 会给你你想要的答案
结果给你:
Because you are setting the fields to INT you have the problem that both xsi:nil="true" fields and the value 0 will end up as 0 as the default value for INT Is 0.
You could convert to VARCHAR first to detect the empty string ('') that string fields containing xsi:nil="true" produce and then convert the result to INT.
This SELECT will give you the answer you are after
The result of this gives you:
我只是根据需要使用 NULLIF 将空字符串转换为 NULL。
您现在可以使用
FOR XML
生成nil
,但抱歉,我从未弄清楚如何解析它......I've simply used NULLIF to turn empty strings into NULLs as needed.
You can generate
nil
now usingFOR XML
, but I've never worked out how to parse it sorry...我建议采用这种方法:
I would sugest this approach:
我不确定您的特定情况是否要求您首先对节点进行子查询,但如果不需要,您可以请求 .value 并提供 xPath。由于 Property1 节点存在,您希望评估 Property1 节点的 text() 而不是节点本身:
除了确保这在其他情况下有效之外,您还可以在 @a.nodes xPath 语句中提供最详细的元素路径并使用“../”而不是子查询节点结果。
I'm not sure if your particular case requires you to sub-query the nodes first, but if not you can request the .value and provide the xPath. Since the Property1 node exists, you want to evaluate the text() of the Property1 node and not the node itself:
In addition to make sure this works in other cases you can provide the most detailed element path in the @a.nodes xPath statment and walk up with "../" instead of sub-querying the node results.
执行此操作的一个巧妙方法是从需要 null 值的 XML 中删除 Property1 节点。因此,无论您希望结果集中的哪个节点为空,都不要将其添加到 XML 中。这样您就不必添加 xsi:nill 属性。
因此,下面也会导致 null:
在上面的示例中可以看出,没有 Property1 节点,因此它将导致 null 值
A clever way of doing this would be to remove the Property1 node from the XML where null values are desired. So what ever node you want to be null in your result set just do not add it to the XML. In this way you will not have to add the xsi:nill attribute as well.
So Below will also result in a null:
It can be seen in the above example that there is no Property1 node hence it will result in a null value
就我而言,我使用的是布尔数据类型,因此这里的所有答案不适用于我。如果你使用的是布尔数据类型,你可以尝试这个:
我添加了这段代码:
如果布尔值为空,则进行强制转换,如果是,则返回 null,否则返回 1 或 0。
In my case, I am using data type boolean so all the answer here doesn't apply to me. If you are using boolean data type, you can try this one:
I added this code:
Which cast if the boolean is null, if it is, it will return null, or else it will return 1 or 0.