在SQL Server的OPENXML函数中将空元素视为空值

时间:2010-05-20 21:22:47

标签: sql-server xml tsql null openxml

我有以下(高度简化的)XML文档,我正在使用OPENXML函数读入我的数据库:

<root>
    <row>
        <bar>123</bar>
    </row>
    <row>
        <bar>0</bar>
    </row>
    <row>
        <bar></bar>
    </row>
</root>

我正在导入数据库,如下所示:

insert into [Foo]
    ([bar])
select
    ds.[bar]
from openxml(@xmlHandle, 'root/row', 2)
with ([bar] int) ds

问题是OPENXML将int数据类型的空字段转换为零,所以这会插入到我的表中:

bar
----
123
0
0

我想要插入表格中的是:

bar
----
123
0
NULL

如何让OPENXML函数将空字段视为NULL并且默认情况下不将其转换为零?

4 个答案:

答案 0 :(得分:7)

刚遇到类似的问题,并使用SQL中的NULLIF函数解决了这个问题。

NULLIF on MSDN

我相信你也会忽略它:)

insert into [Foo]
    ([bar])
select
    NULLIF(ds.[bar], '')
from openxml(@xmlHandle, 'root/row', 2)
with ([bar] nvarchar(20)) ds

消除CASE... END语句创建的混乱。

希望它有所帮助!

答案 1 :(得分:5)

由于没有人有任何想法,这就是我如何“解决”它,虽然这对我来说似乎是一个黑客攻击:

insert into [Foo]
    ([bar])
select
    isnull(ds.[bar], '') when '' then null else CAST(ds.[bar] as int) end
from openxml(@xmlHandle, 'root/row', 2)
with ([bar] nvarchar(20)) ds

答案 2 :(得分:3)

不确定你的xml是如何“高度简化”的,但是如果你有一个指定null的属性,你也可以做一些类似于答案的here;基本上是:

<root>
<row>
    <bar>123</bar>
</row>
<row>
    <bar>0</bar>
</row>
<row>
    <bar nil="true"></bar>
</row>

select ds.bar
from openxml(@xmlHandle, 'root/row', 2) with (
  [bar] nvarchar(20) 'bar[not(@nil = "true")]'
) ds

此方案对我有用

答案 3 :(得分:0)

我最初将NULLIF用作already suggested,但在WITH模式中找到了另一个选项:

SELECT bar
FROM openxml(@xmlHandle, 'root/row', 2)
WITH (
  [bar] nvarchar(20) 'bar[string-length(.)>0]'
)

我正在查看数百列和数千行,因此大小合适但并不庞大。我发现此或NULLIF的性能基本相同,但是我喜欢将定义保留在WITH子句中,以便SELECT可以保持整洁(因为我倾向于在那里发生许多其他事情)。

YMMV