我需要生成一个EXCEL Like XML文件,从SQL Server中的表中插入数据。经过一些研究后,我使用FOR XML EXPLICIT模式获得了以下SQL Server脚本:
DECLARE @T AS TABLE (col1 VARCHAR(20), col2 VARCHAR(20));
INSERT INTO @T VALUES('Row1 Col1', 'Row1 Col2');
INSERT INTO @T VALUES('Row2 Col1', 'Row2 Col2');
SELECT 1 as 'Tag'
,NULL as 'Parent'
,NULL as 'Row!1'
,NULL as 'Cell!2'
,NULL as 'Cell!2!Index'
,NULL as 'Cell!2!StyleID'
,NULL as 'Data!3'
,NULL as 'Data!3!Type'
,NULL as 'Cell!2'
,NULL as 'Cell!2!Index'
,NULL as 'Cell!2!StyleID'
,NULL as 'Data!3'
,NULL as 'Data!3!Type'
,ROW_NUMBER() OVER (ORDER BY col1) as 'Row!1!A!HIDE'
,1 as 'Row!1!B!HIDE'
FROM @T
UNION ALL
SELECT 2
,1
,NULL
,NULL
,'1'
,'s1'
,NULL
,NULL
,NULL
,'2'
,'s2'
,NULL
,NULL
,ROW_NUMBER() OVER (ORDER BY col1)
,2
FROM @T
UNION ALL
SELECT 3
,2
,NULL
,NULL
,NULL
,NULL
,col1
,'String'
,NULL
,NULL
,NULL
,col2
,'String'
,ROW_NUMBER() OVER (ORDER BY col1)
,3
FROM @T
ORDER BY 14, 15
FOR XML EXPLICIT
GO
我得到的结果是:
<Row>
<Cell Index="1" StyleID="s1" Index="2" StyleID="s2">
<Data Type="String" Type="String">Row1 Col1Row1 Col2</Data>
</Cell>
</Row>
<Row>
<Cell Index="1" StyleID="s1" Index="2" StyleID="s2">
<Data Type="String" Type="String">Row2 Col1Row2 Col2</Data>
</Cell>
</Row>
我期望的结果是:
<Row>
<Cell Index="1" StyleID="s1">
<Data Type="String">Row1 Col1</Data>
</Cell>
<Cell Index="2" StyleID="s2">
<Data Type="String">Row1 Col2</Data>
</Cell>
</Row>
<Row>
<Cell Index="1" StyleID="s1">
<Data Type="String">Row2 Col1</Data>
</Cell>
<Cell Index="2" StyleID="s2">
<Data Type="String">Row2 Col2</Data>
</Cell>
</Row>
任何帮助都将不胜感激。
答案 0 :(得分:0)
这可以为您提供所需的结果,但不确定这是否适用于您提供的测试数据。
SELECT
1 AS 'Tag',
NULL AS 'Parent',
NULL AS 'Row!1',
NULL AS 'Cell!2',
NULL AS 'Cell!2!Index',
NULL AS 'Cell!2!StyleID',
NULL AS 'Data!3',
NULL AS 'Data!3!Type',
ROW_NUMBER() OVER (ORDER BY col1) AS 'Row!1!A!HIDE',
1 AS 'Row!1!B!HIDE'
FROM
@T
UNION ALL
SELECT
2,
1,
NULL,
NULL,
'1',
's1',
NULL,
NULL,
ROW_NUMBER() OVER (ORDER BY col1),
2
FROM
@T
UNION ALL
SELECT
3,
2,
NULL,
NULL,
NULL,
NULL,
col1,
'String',
ROW_NUMBER() OVER (ORDER BY col1),
2
FROM
@T
UNION ALL
SELECT
2,
1,
NULL,
NULL,
'2',
's2',
NULL,
NULL,
ROW_NUMBER() OVER (ORDER BY col1),
3
FROM
@T
UNION ALL
SELECT
3,
2,
NULL,
NULL,
NULL,
NULL,
col2,
'String',
ROW_NUMBER() OVER (ORDER BY col1),
3
FROM
@T
ORDER BY
9,
10
FOR
XML EXPLICIT
GO
诀窍是在调用FOR XML EXPLICIT
之前以正确的顺序获取数据它应该看起来与此类似
Tag Parent Row!1 Cell!2 Cell!2!Index Cell!2!StyleID Data!3 Data!3!Type Row!1!A!HIDE Row!1!B!HIDE
1 NULL NULL NULL NULL NULL NULL NULL 1 1
2 1 NULL NULL 1 s1 NULL NULL 1 2
3 2 NULL NULL NULL NULL Row1 Col1 String 1 2
2 1 NULL NULL 2 s2 NULL NULL 1 3
3 2 NULL NULL NULL NULL Row1 Col2 String 1 3
1 NULL NULL NULL NULL NULL NULL NULL 2 1
2 1 NULL NULL 1 s1 NULL NULL 2 2
3 2 NULL NULL NULL NULL Row2 Col1 String 2 2
2 1 NULL NULL 2 s2 NULL NULL 2 3
3 2 NULL NULL NULL NULL Row2 Col2 String 2 3
答案 1 :(得分:0)
我设法使用FOR XML PATH模式找到了更好的方法:
DECLARE @T AS TABLE (
col1 VARCHAR(20),
col2 VARCHAR(20),
col3 VARCHAR(20)
);
INSERT INTO @T VALUES
('Row1 Col1','Row1 Col2','Row1 Col3'),
('Row2 Col1',NULL,'Row2 Col3'),
('Row3 Col1','Row3 Col2',NULL);
SELECT
'1' as 'Cell/@Index',
's1' as 'Cell/@StyleID',
'String' as 'Cell/Data/@Type',
col1 as 'Cell/Data',
'',
'2' as 'Cell/@Index',
's2' as 'Cell/@StyleID',
'String' as 'Cell/Data/@Type',
col2 as 'Cell/Data',
'',
'3' as 'Cell/@Index',
's3' as 'Cell/@StyleID',
'String' as 'Cell/Data/@Type',
col3 as 'Cell/Data'
FROM @T
FOR XML PATH ('Row')
GO
我得到了理想的结果:
<Row>
<Cell Index="1" StyleID="s1">
<Data Type="String">Row1 Col1</Data>
</Cell>
<Cell Index="2" StyleID="s2">
<Data Type="String">Row1 Col2</Data>
</Cell>
<Cell Index="3" StyleID="s3">
<Data Type="String">Row1 Col3</Data>
</Cell>
</Row>
<Row>
<Cell Index="1" StyleID="s1">
<Data Type="String">Row2 Col1</Data>
</Cell>
<Cell Index="2" StyleID="s2">
<Data Type="String" />
</Cell>
<Cell Index="3" StyleID="s3">
<Data Type="String">Row2 Col3</Data>
</Cell>
</Row>
<Row>
<Cell Index="1" StyleID="s1">
<Data Type="String">Row3 Col1</Data>
</Cell>
<Cell Index="2" StyleID="s2">
<Data Type="String">Row3 Col2</Data>
</Cell>
<Cell Index="3" StyleID="s3">
<Data Type="String" />
</Cell>
</Row>
在sql语句中添加空字符串('')可以解决问题。
但它变得越来越好:我不想为NULL值打印标签。我应该怎么做呢?这就是答案:
DECLARE @T AS TABLE (
col1 VARCHAR(20),
col2 VARCHAR(20),
col3 VARCHAR(20)
);
INSERT INTO @T VALUES
('Row1 Col1','Row1 Col2','Row1 Col3'),
('Row2 Col1',NULL,'Row2 Col3'),
('Row3 Col1','Row3 Col2',NULL);
SELECT
'Cell/@Index' = case when col1 is not null then '1' else NULL end,
'Cell/@StyleID' = case when col1 is not null then 's1' else NULL end,
'Cell/Data/@Type' = case when col1 is not null then 'String' else NULL end,
col1 as 'Cell/Data',
'',
'Cell/@Index' = case when col2 is not null then '2' else NULL end,
'Cell/@StyleID' = case when col2 is not null then 's2' else NULL end,
'Cell/Data/@Type' = case when col2 is not null then 'String' else NULL end,
col2 as 'Cell/Data',
'',
'Cell/@Index' = case when col3 is not null then '3' else NULL end,
'Cell/@StyleID' = case when col3 is not null then 's3' else NULL end,
'Cell/Data/@Type' = case when col3 is not null then 'String' else NULL end,
col3 as 'Cell/Data'
FROM @T
FOR XML PATH ('Row')
GO
我得到了更好的结果:
<Row>
<Cell Index="1" StyleID="s1">
<Data Type="String">Row1 Col1</Data>
</Cell>
<Cell Index="2" StyleID="s2">
<Data Type="String">Row1 Col2</Data>
</Cell>
<Cell Index="3" StyleID="s3">
<Data Type="String">Row1 Col3</Data>
</Cell>
</Row>
<Row>
<Cell Index="1" StyleID="s1">
<Data Type="String">Row2 Col1</Data>
</Cell>
<Cell Index="3" StyleID="s3">
<Data Type="String">Row2 Col3</Data>
</Cell>
</Row>
<Row>
<Cell Index="1" StyleID="s1">
<Data Type="String">Row3 Col1</Data>
</Cell>
<Cell Index="2" StyleID="s2">
<Data Type="String">Row3 Col2</Data>
</Cell>
</Row>
我在SQLS 2008上使用CASE做过。对于SQLS 2012,您可以使用IIF。
最后,我想在属性上添加名称空间指示符。我这样做了:
DECLARE @T AS TABLE (
col1 VARCHAR(20),
col2 VARCHAR(20),
col3 VARCHAR(20)
);
INSERT INTO @T VALUES
('Row1 Col1','Row1 Col2','Row1 Col3'),
('Row2 Col1',NULL,'Row2 Col3'),
('Row3 Col1','Row3 Col2',NULL);
WITH XMLNAMESPACES ('urn:schemas-microsoft-com:office:spreadsheet' as ss)
SELECT
'Cell/@ss:Index' = case when col1 is not null then '1' else NULL end,
'Cell/@ss:StyleID' = case when col1 is not null then 's1' else NULL end,
'Cell/Data/@ss:Type' = case when col1 is not null then 'String' else NULL end,
col1 as 'Cell/Data',
'',
'Cell/@ss:Index' = case when col2 is not null then '2' else NULL end,
'Cell/@ss:StyleID' = case when col2 is not null then 's2' else NULL end,
'Cell/Data/@ss:Type' = case when col2 is not null then 'String' else NULL end,
col2 as 'Cell/Data',
'',
'Cell/@ss:Index' = case when col3 is not null then '3' else NULL end,
'Cell/@ss:StyleID' = case when col3 is not null then 's3' else NULL end,
'Cell/Data/@ss:Type' = case when col3 is not null then 'String' else NULL end,
col3 as 'Cell/Data'
FROM @T
FOR XML PATH ('Row'), ROOT ('Worksheet')
GO
我得到的结果与我正在寻找的结果更接近:
<Worksheet xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<Row>
<Cell ss:Index="1" ss:StyleID="s1">
<Data ss:Type="String">Row1 Col1</Data>
</Cell>
<Cell ss:Index="2" ss:StyleID="s2">
<Data ss:Type="String">Row1 Col2</Data>
</Cell>
<Cell ss:Index="3" ss:StyleID="s3">
<Data ss:Type="String">Row1 Col3</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="1" ss:StyleID="s1">
<Data ss:Type="String">Row2 Col1</Data>
</Cell>
<Cell ss:Index="3" ss:StyleID="s3">
<Data ss:Type="String">Row2 Col3</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="1" ss:StyleID="s1">
<Data ss:Type="String">Row3 Col1</Data>
</Cell>
<Cell ss:Index="2" ss:StyleID="s2">
<Data ss:Type="String">Row3 Col2</Data>
</Cell>
</Row>
</Worksheet>
我必须在XML文档的中间插入这个片段,所以如果我可以摆脱第一行和最后一行以连接固定的页眉和页脚,那将是很好的。
希望这有助于其他人。