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)
我怎样才能做到这一点?
那这个呢:
;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)