2013-09-23 62 views
1

我有以下的C#類SQL服務器讀取XML值作爲空字符串

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

我做到這一點使用:

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

在存儲過程中生成的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應該是空字符串。

我該如何調整以確保空值保留爲空值,空字符串保留爲空字符串?

由於

+0

如果你說:「RAD的XML」你的意思是「讀XML」? –

+0

爲什麼你需要將它轉換爲XML傳遞給存儲過程,只是將它從XML中分離出來,返回到離散的字段中?只需將離散值傳遞到存儲過程即可。 –

+0

最大,對於「rad」,讀取「讀取」。這條消息中的XML非常簡單,我的實際XML更加複雜,並且允許我將一批對象傳遞給我的sproc,然後可以遍歷它們。 – DrGriff

回答

0

的XElement構造可處理NULL和空不同,但XML規範認爲< X />和< X> </X>是相同的。 SQL服務器XQuery也一樣對待它們。

如果您希望SQL服務器區分空的&空元素,則需要在C#代碼中構建XML時完全排除空元素。例如,下面的對待元素B爲空& 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); 
+0

您的xml節點選擇器不使用「text()」方法,因此可能會在有子元素時返回預期結果,例如,當@x = ' ABC D1 D2'。所以當你使用text()方法(例如「nref.value('(B/text())[1]','varchar(10)')[B]」)時,B和C的值都是返回爲NULL。 – DrGriff

+1

@DGGriff你是對的,我沒有考慮過。儘管我試圖做的主要觀點是< X />和< X>< /X> *在每個XML規範中的含義*是相同的。所以你需要實際排除元素(當你在你的C#代碼中構造XML時)來表示NULL和空。無論如何,我編輯答案提供一個基於EXIST方法的可能解決方案。希望能幫助到你。 –

+0

不知道爲什麼這一個是downvoted,這是我的upvote :)這不是很優雅的方式來做到這一點,但它應該工作 –