我正在尝试在进行连接时将null xml元素替换为null值。我犯了一些愚蠢的错误。我想区分空值和空值。我正在使用OpenXML来解析XML数据,并且代码中缺少一些东西来读取基于null的param元素。
我正在使用Server Server 2014.
请建议。
DECLARE @message_body XML;
DECLARE @XMLParameterData Table
(SeqID INT Identity(1,1),
ParamValue varchar(max))
DECLARE @docRef int
DECLARE @dataPath nvarchar(255)
DECLARE @mappingType int = 2 --Element-Centric mapping
Select @message_body = N'<AsyncRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ParamList> <Param>Bruce</Param>
<Param>Wa''yne</Param>
<Param>Bruce@karan.com</Param>
<Param>Coke</Param>
<Param>20000</Param>
<Param xsi:nil="true"/>
<Param></Param>
</ParamList>
</AsyncRequest>';
Set @dataPath = '/AsyncRequest/ParamList/Param'
EXEC sp_xml_preparedocument @docRef output, @message_body
INSERT INTO @XMLParameterData(ParamValue)
Select * From OpenXML(@docRef, @dataPath, @mappingType)
WITH
(
valx varchar(max) '.'
)
-- the xml document ref needs to be released ASAP
EXEC sp_xml_removedocument @docRef
SELECT * From @XMLParameterData
DECLARE @CSVString varchar(max)
SELECT @CSVString = STUFF(
(SELECT ', ' +
CHAR(34) + ParamValue + CHAR(34)
FROM @XMLParameterData
ORDER BY SeqID
FOR XML PATH('')
), 1, 1, '')
SELECT @CSVString as CSVTest
输出: - &#34; Bruce&#34;,&#34; Wa&#39; yne&#34;,&#34; Bruce@karan.com",&#34; Coke&#34;,&#34; 20000&# 34;,&#34;&#34;,&#34;&#34;
所需的输出: - &#34; Bruce&#34;,&#34; Wa&#39; yne&#34;,&#34; Bruce@karan.com",&#34; Coke&#34;,&#34; 20000&# 34;, NULL ,&#34;&#34;
答案 0 :(得分:2)
保持简单!使用CASE WHEN
检查@xsi:nil="true"
和.nodes
是否代替OPENXML
:
DECLARE @message_body XML,
@output nvarchar(max);
select @message_body = N'<AsyncRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ParamList>
<Param>Bruce</Param>
<Param>Wa''yne</Param>
<Param>Bruce@karan.com</Param>
<Param>Coke</Param>
<Param>20000</Param>
<Param xsi:nil="true"/>
<Param></Param>
</ParamList>
</AsyncRequest>';
SELECT @output = STUFF((
SELECT
CASE WHEN t.v.value('@xsi:nil','nvarchar(max)') = 'true' THEN ',NULL'
ELSE ',"'+t.v.value('.','nvarchar(max)') + '"'
END
FROM @message_body.nodes('AsyncRequest/ParamList/Param') as t(v)
FOR XML PATH('')
),1,1,'')
SELECT @output
将返回:
"Bruce","Wa'yne","Bruce@karan.com","Coke","20000",NULL,""
答案 1 :(得分:1)
这个怎么样(我通过使用xml.nodes而不是xml文档略微简化了你的代码)。
它使用xml查询表达式.[not(@xsi:nil = "true")]
返回null,其中xsi:nil为true。
然后我使用COALESCE
返回字符串&#39; NULL&#39;当返回NULL
时:
DECLARE @message_body XML;
DECLARE @XMLParameterData Table
(SeqID INT Identity(1,1),
ParamValue varchar(max))
Select @message_body = N'<AsyncRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><ParamList><Param>Bruce</Param><Param>Wa''yne</Param>
<Param>Bruce@karan.com</Param>
<Param>Coke</Param>
<Param>20000</Param>
<Param xsi:nil="true"/>
<Param></Param>
</ParamList>
</AsyncRequest>';
INSERT INTO @XMLParameterData(ParamValue)
SELECT T.c.value('.[not(@xsi:nil = "true")]', 'varchar(max)') AS result
FROM @message_body.nodes('/AsyncRequest/ParamList/Param')T(c)
SELECT * From @XMLParameterData
DECLARE @CSVString varchar(max)
SELECT @CSVString = STUFF(
(SELECT ', ' +
CHAR(34) + COALESCE(ParamValue, 'NULL') + CHAR(34)
FROM @XMLParameterData
ORDER BY SeqID
FOR XML PATH('')
), 1, 1, '')
SELECT @CSVString as CSVTest
返回: &#34; Bruce&#34;,&#34; Wa&#39; yne&#34;,&#34; Bruce@karan.com",&#34; Coke&#34;,&#34; 20000&# 34;,&#34; NULL&#34;,&#34;&#34;
答案 2 :(得分:0)
您想要达到的目标不是标准行为。你可能会期待以下:
DECLARE @message_body XML = N'<AsyncRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ParamList>
<Param>Bruce</Param>
<Param>Wa''yne</Param>
<Param>Bruce@karan.com</Param>
<Param>Coke</Param>
<Param>20000</Param>
<Param xsi:nil="true"/>
<Param></Param>
</ParamList>
</AsyncRequest>';
SELECT X.value('.[not(@xsi:nil="true")]', 'nvarchar(MAX)') Value
FROM @message_body.nodes('//Param') T(X)
哪个收益率:
Value
-----
Bruce
Wa'yne
Bruce@karan.com
Coke
20000
NULL
(empty string here)
您可能需要来自节点的 text ,这更加标准化:
SELECT X.value('text()[1]', 'nvarchar(MAX)') Value
FROM @message_body.nodes('//Param') T(X)
Value
-----
Bruce
Wa'yne
Bruce@karan.com
Coke
20000
NULL
NULL
请注意,<element/>
和<element></element>
是同义词。无论你怎么写,它都是空的。问问自己:第一个<element/>
空字符串?这将导致长时间的讨论 - 这都是解释的问题。您还可以考虑使用xml:space
属性来处理空格。