TSQL FOR XML 格式化
TSQL FOR XML Formatting
我有一个 table,我想将其转换为 XML 格式。 table 称为 tempTable 并保存数据:
REF DESC QTY
100001 Normal 1
100002 OOH 1
我需要以这种给定的格式创建 XML:
<row>
<LIN NUM="1">
<FLD NAME="REF">100001</FLD>
<FLD NAME="DES">Normal</FLD>
<FLD NAME="QTY">1</FLD>
</LIN>
<LIN NUM="2">
<FLD NAME="REF">100002</FLD>
<FLD NAME="DES">OOH</FLD>
<FLD NAME="QTY">1</FLD>
</LIN>
</row>
我试过下面的代码:
SET @line = (SELECT '1' AS '@NUM', REF AS 'REF', DES AS 'DES', QTY AS 'QTY' FROM tempTable WHERE ORDER= @ORDER
FOR XML PATH('LIN'))
SELECT @line
FOR XML PATH
但是这会产生:
<row>
<LIN NUM="1">
<REF>100001</REF>
<DES>Normal</DES>
<QTY>1</QTY>
</LIN>
<LIN NUM="1">
<REF>100002</REF>
<DES>OOH</DES>
<QTY>1</QTY>
</LIN>
</row>
有谁知道我该怎么做:
- A) 将 'LIN' 'NUM' 属性更改为根据数量递增
该订单的记录?
B) 将 'Name' 属性添加到 'LIN' 详细信息并更改
字段名称为 'FLD'。当我尝试将名称更改为 'FLD' 时
将值连接到单个节点上,如下所示:
<row>
<LIN NUM="1">
<FLD>100001Normal1</FLD>
</LIN>
<LIN NUM="1">
<FLD>100002OOH1</FLD>
</LIN>
</row>
我假设我是否可以添加 'NAME' 属性来分隔值?
任何 advice/help 将不胜感激。
谢谢
declare @tempTable table (Ref int, Des varchar(100), Qty int)
insert into @tempTable values (100001, 'Normal', 1), (100002, 'OOH', 1)
SELECT ROW_NUMBER() OVER (ORDER BY Ref) AS '@NUM',
'REF' AS 'FLD/@NAME', REF AS 'FLD', '',
'DES' AS 'FLD/@NAME', DES AS 'FLD', '',
'QTY' AS 'FLD/@NAME', QTY AS 'FLD'
FROM @tempTable
FOR XML PATH('LIN'), ROOT ('row')
产生:
<row>
<LIN NUM="1">
<FLD NAME="REF">100001</FLD>
<FLD NAME="DES">Normal</FLD>
<FLD NAME="QTY">1</FLD>
</LIN>
<LIN NUM="2">
<FLD NAME="REF">100002</FLD>
<FLD NAME="DES">OOH</FLD>
<FLD NAME="QTY">1</FLD>
</LIN>
</row>
在 的帮助下,因为 select 中的节点和属性之间没有空字符串,SQL 服务器给出错误:
Attribute-centric column 'FLD/@NAME' must not come after a non-attribute-centric sibling in XML hierarchy in FOR XML PATH.
编辑:如评论中所述, 解释了空引号技巧为何有效。
总结:
- 在
FOR XML PATH
中,没有名称的列成为文本节点
NULL
或''
因此成为空文本节点
- 您可以使用
AS *
将命名列转换为未命名列
- 这有助于将先前的输出节点与下一个输出节点分开,以便 SQL 服务器知道例如为下一列开始一个新元素。否则,当属性已经存在于它认为的 "current" 元素
上时,它会感到困惑
DECLARE @t TABLE (ref varchar(10), descr varchar(10), qty varchar(3))
insert into @t
values('100001', 'Normal', '1'),('10002','OOH','1')
SELECT ROW_NUMBER() OVER (ORDER BY a.ref) AS '@NUM',
(SELECT 'REF' AS 'FLD/@NAME'
,ref AS 'FLD'
FROM @t AS FLD
WHERE FLD.ref = a.ref
FOR XML PATH(''), TYPE),
(SELECT 'DESCR' AS 'FLD/@DESCR'
,descr AS 'FLD'
FROM @t AS FLD
WHERE FLD.ref = a.ref
FOR XML PATH(''), TYPE),
(SELECT 'QTY' AS 'FLD/@QTY'
,QTY AS 'FLD'
FROM @t AS FLD
WHERE FLD.ref = a.ref
FOR XML PATH(''), TYPE)
FROM @t AS a
FOR XML PATH('LIN'), ROOT('row')
我有一个 table,我想将其转换为 XML 格式。 table 称为 tempTable 并保存数据:
REF DESC QTY
100001 Normal 1
100002 OOH 1
我需要以这种给定的格式创建 XML:
<row>
<LIN NUM="1">
<FLD NAME="REF">100001</FLD>
<FLD NAME="DES">Normal</FLD>
<FLD NAME="QTY">1</FLD>
</LIN>
<LIN NUM="2">
<FLD NAME="REF">100002</FLD>
<FLD NAME="DES">OOH</FLD>
<FLD NAME="QTY">1</FLD>
</LIN>
</row>
我试过下面的代码:
SET @line = (SELECT '1' AS '@NUM', REF AS 'REF', DES AS 'DES', QTY AS 'QTY' FROM tempTable WHERE ORDER= @ORDER
FOR XML PATH('LIN'))
SELECT @line
FOR XML PATH
但是这会产生:
<row>
<LIN NUM="1">
<REF>100001</REF>
<DES>Normal</DES>
<QTY>1</QTY>
</LIN>
<LIN NUM="1">
<REF>100002</REF>
<DES>OOH</DES>
<QTY>1</QTY>
</LIN>
</row>
有谁知道我该怎么做:
- A) 将 'LIN' 'NUM' 属性更改为根据数量递增 该订单的记录?
B) 将 'Name' 属性添加到 'LIN' 详细信息并更改 字段名称为 'FLD'。当我尝试将名称更改为 'FLD' 时 将值连接到单个节点上,如下所示:
<row> <LIN NUM="1"> <FLD>100001Normal1</FLD> </LIN> <LIN NUM="1"> <FLD>100002OOH1</FLD> </LIN> </row>
我假设我是否可以添加 'NAME' 属性来分隔值?
任何 advice/help 将不胜感激。
谢谢
declare @tempTable table (Ref int, Des varchar(100), Qty int)
insert into @tempTable values (100001, 'Normal', 1), (100002, 'OOH', 1)
SELECT ROW_NUMBER() OVER (ORDER BY Ref) AS '@NUM',
'REF' AS 'FLD/@NAME', REF AS 'FLD', '',
'DES' AS 'FLD/@NAME', DES AS 'FLD', '',
'QTY' AS 'FLD/@NAME', QTY AS 'FLD'
FROM @tempTable
FOR XML PATH('LIN'), ROOT ('row')
产生:
<row>
<LIN NUM="1">
<FLD NAME="REF">100001</FLD>
<FLD NAME="DES">Normal</FLD>
<FLD NAME="QTY">1</FLD>
</LIN>
<LIN NUM="2">
<FLD NAME="REF">100002</FLD>
<FLD NAME="DES">OOH</FLD>
<FLD NAME="QTY">1</FLD>
</LIN>
</row>
在 的帮助下,因为 select 中的节点和属性之间没有空字符串,SQL 服务器给出错误:
Attribute-centric column 'FLD/@NAME' must not come after a non-attribute-centric sibling in XML hierarchy in FOR XML PATH.
编辑:如评论中所述,
总结:
- 在
FOR XML PATH
中,没有名称的列成为文本节点NULL
或''
因此成为空文本节点- 您可以使用
AS *
将命名列转换为未命名列
- 这有助于将先前的输出节点与下一个输出节点分开,以便 SQL 服务器知道例如为下一列开始一个新元素。否则,当属性已经存在于它认为的 "current" 元素 上时,它会感到困惑
DECLARE @t TABLE (ref varchar(10), descr varchar(10), qty varchar(3))
insert into @t
values('100001', 'Normal', '1'),('10002','OOH','1')
SELECT ROW_NUMBER() OVER (ORDER BY a.ref) AS '@NUM',
(SELECT 'REF' AS 'FLD/@NAME'
,ref AS 'FLD'
FROM @t AS FLD
WHERE FLD.ref = a.ref
FOR XML PATH(''), TYPE),
(SELECT 'DESCR' AS 'FLD/@DESCR'
,descr AS 'FLD'
FROM @t AS FLD
WHERE FLD.ref = a.ref
FOR XML PATH(''), TYPE),
(SELECT 'QTY' AS 'FLD/@QTY'
,QTY AS 'FLD'
FROM @t AS FLD
WHERE FLD.ref = a.ref
FOR XML PATH(''), TYPE)
FROM @t AS a
FOR XML PATH('LIN'), ROOT('row')