2016-09-21 2 views
2

연결을 수행하는 동안 null xml 요소를 null 값으로 바꾸려고합니다. 그리고 저는 어리석은 실수를 저지르고 있습니다. 빈 값과 널 값을 구별하고 싶습니다. OpenXML을 사용하여 XML 데이터를 구문 분석하고 null 기반 param 요소를 읽는 코드에 누락 된 것이 있습니다.Sql Server - XML의 경우 - 요소의 null 값 가져 오기

내가 제안하십시오 서버 서버 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>[email protected]</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 

출력 : - "브루스", "Wa'yne", "[email protected]", "콜라", "20000", "", ""

원하는 출력 : - "브루스", "Wa'yne", "[email protected]", "콜라", "20000", NULL ","나는 약간하여 코드를 단순화 (이것에 대해 어떻게

답변

2

간단하게하십시오!

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>[email protected]</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 

반환합니다 : @xsi:nil="true".nodes 대신 OPENXML가 있는지 확인하는 CASE WHEN를 사용하여 당신이 달성하려고하는 무엇

"Bruce","Wa'yne","[email protected]","Coke","20000",NULL,"" 
+0

고마워, 잘 했어 :-) – Karan

+0

내 기쁨! :) – gofr1

1

XML 문서가 아닌 xml.nodes 사용).

xsi : nil이 true 인 경우 xml 쿼리 식 .[not(@xsi:nil = "true")]을 사용하여 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>[email protected]</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 

이 반환 :

나는 그 문자열 NULL이 반환 'NULL'돌아 COALESCE을 사용 "브루스", "Wa'yne", "[email protected]"를, "콜라", "20000", "NULL", ""

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>[email protected]</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) 

가 : <element/><element></element> 동의어가

SELECT X.value('text()[1]', 'nvarchar(MAX)') Value 
FROM @message_body.nodes('//Param') T(X) 

Value 
----- 
Bruce 
Wa'yne 
[email protected] 
Coke 
20000 
NULL 
NULL 

하는 것으로 :

Value 
----- 
Bruce 
Wa'yne 
[email protected] 
Coke 
20000 
NULL 
(empty string here) 

당신은 더 위하여 표준화이다 노드에서 텍스트을 할 수 있습니다 당신은 propbably 다음과 같은 기대 . 어떻게 쓰든간에 그것은 비어 있습니다. 자신에게 물어보십시오 : 먼저 <element/> 빈 문자열입니까? 그것은 오랜 토론을 이끌 것입니다. 그것은 모두 해석의 문제입니다. 공백을 처리하려면 xml:space 속성을 고려할 수도 있습니다.