SQL Server将xml值读取为空字符串

时间:2013-09-23 13:15:52

标签: sql sql-server xml sql-server-2008 sqlxml

我有以下c#class

public class Data
{
    public string A {get;set;}
    public string B {get;set;}
    public string C {get;set;}
}

我在我的代码中创建了一个这样的实例:

var d = new Data { A = "abc", B = string.Empty, C = null};

我需要将其转换为XML并将其传递给SQL Server 2008中的sproc。

我是这样做的:

var xml = new XElement("Data",
    new XElement("A", d.A),
    new XElement("B", d.B),
    new XElement("C", d.C));

sproc中的结果XML是:

<Data>
    <A>abc</A>
    <B></B>
    <C />
</Data>

因此,空字符串与空值之间存在差异。

然后在SQL中,我使用以下语法来读取XML:

INSERT INTO #myTable
SELECT 
  nref.value('(A/text())[1]', 'uniqueidentifier') [A],
  nref.value('(B/text())[1]', 'uniqueidentifier') [B],
  nref.value('(C/text())[1]', 'uniqueidentifier') [C],
FROM @DataXml.nodes('/Data') AS R(nref);

但是这给我提供了B和C都为NULL,其中B应该是空字符串。

我如何调整它以确保空值保持为空,空字符串保持为空字符串?

由于

1 个答案:

答案 0 :(得分:0)

XElement构造函数可以不同地处理NULL和空,但XML规范考虑&lt; X /&gt;和&lt; X&GT;&LT; / X&GT;是相同的。 SQL Server XQuery也同样对待它们。

如果您希望SQL服务器区分空&amp; null元素,在C#代码中构造XML时,需要完全排除null元素。例如,下面将元素B视为空&amp;元素C为NULL,因为它丢失了:

declare @x xml = 
'<Data><A>abc</A><B></B></Data>'

SELECT 
  nref.value('(A/text())[1]', 'varchar') [A],
  isnull(nref.value('(B/text())[1]', 'varchar'), case when nref.exist('./B') = 1 then '' end) [B],
  isnull(nref.value('(C/text())[1]', 'varchar'), case when nref.exist('./C') = 1 then '' end) [C]
FROM @x.nodes('/Data') AS R(nref);