SQL Server使用CTE将xml转换为csv - 当前被忽略的null

Ang*_*ela 7 xml sql sql-server csv

我正在使用CTE将xml转换为csv,以便可以将其导出到文件中,但是如果我有一个空的xml标记,则当前会被忽略.这是我之前非常有用的帖子的初步解决方案:https: //stackoverflow.com/a/23785202/6260721

这是我的sql:

CREATE TABLE EXPORT_TEST
    (
    DATA varchar(max)
    )

INSERT INTO EXPORT_TEST (DATA)
VALUES ('<EXPORT_DATA><ID>ABC123</ID><PRICE_A>5.6</PRICE_A><PRICE_B></PRICE_B><PRICE_C>8.1</PRICE_C></EXPORT_DATA>')

DECLARE @commaSeparatedValues NVARCHAR(MAX)

DECLARE @xml XML = (SELECT TOP 1 CONVERT(xml,DATA) FROM EXPORT_TEST)

;WITH cte AS (
    SELECT 
        rownr = ROW_NUMBER() OVER (ORDER BY @commaSeparatedValues),
        Tbl.col.query('.') AS [xml]
    FROM @xml.nodes('EXPORT_DATA') Tbl(col)
), cols AS (
    SELECT
        rownr,
        Tbl.Col.value('.', 'nvarchar(max)') AS Value
    FROM cte
    CROSS APPLY cte.xml.nodes('//text()') Tbl(Col) 
)
INSERT INTO EXPORT_TEST(DATA)
SELECT DISTINCT
     STUFF((
       SELECT ',' + IIF(ISNUMERIC(value) = 1, Value, '''' + Value + '''')
       FROM cols SSF WHERE SSF.rownr = S.rownr
       FOR XML PATH(''),TYPE
       ).value('.','VARCHAR(MAX)'
     ), 1, 1, '') as DATA
    FROM cols S

SELECT * FROM EXPORT_TEST
Run Code Online (Sandbox Code Playgroud)

目前,它正在返回:

'ABC123',5.6,8.1
Run Code Online (Sandbox Code Playgroud)

但我不希望它忽略PRICE_B,我希望它返回一个空字符串:

'ABC123',5.6,,8.1  <--extra comma required where PRICE_B should be
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

got*_*tqn 0

那这个呢:

;WITH cte AS (
    SELECT 
        rownr = ROW_NUMBER() OVER (ORDER BY @commaSeparatedValues),
        Tbl.col.query('.') AS [xml]
    FROM @xml.nodes('EXPORT_DATA') Tbl(col)
), cols AS (
    SELECT
        rownr,
        Tbl.Col.value('.', 'nvarchar(max)') AS Value
    FROM cte
    CROSS APPLY cte.xml.nodes('EXPORT_DATA/child::node()') Tbl(Col) 
)
INSERT INTO EXPORT_TEST(DATA)
SELECT DISTINCT
     STUFF((
       SELECT ',' + IIF(ISNUMERIC(value) = 1 OR LEN(value) = 0, Value, '''' + Value + '''')
       FROM cols SSF WHERE SSF.rownr = S.rownr
       FOR XML PATH(''),TYPE
       ).value('.','VARCHAR(MAX)'
     ), 1, 1, '') as DATA
    FROM cols S
Run Code Online (Sandbox Code Playgroud)

在第二个 CTE 中使用cte.xml.nodes('EXPORT_DATA/child::node()')将给出所有节点:

;WITH cte AS (
    SELECT 
        rownr = ROW_NUMBER() OVER (ORDER BY @commaSeparatedValues),
        Tbl.col.query('.') AS [xml]
    FROM @xml.nodes('EXPORT_DATA') Tbl(col)
)
    SELECT
        rownr
        ,Tbl.Col.query('.')
        ,Tbl.Col.value('.', 'nvarchar(max)') AS Value
    FROM cte
    CROSS APPLY cte.xml.nodes('EXPORT_DATA/child::node()') Tbl(Col) 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

然后,在连接中我们需要添加空字符串检查:

IIF(ISNUMERIC(value) = 1 OR LEN(value) = 0, Value, '''' + Value + '''')
Run Code Online (Sandbox Code Playgroud)