tsql:将列转换为xml列,每行一个xml

时间:2011-02-11 19:04:45

标签: sql-server xml tsql

我的例子:

表:(col1 int, col2 int)
样本数据(在运行时不知道真实数据):

1,1
2,2
3,3
4,4

预期结果:仅一列(xml)
和4行

row1: <cols><col1>1</col1><col2>1</col2></cols>
row2: <cols><col1>2</col1><col2>2</col2></cols>
row3: <cols><col1>3</col1><col2>3</col2></cols>
row4: <cols><col1>4</col1><col2>4</col2></cols>

对不起,主持人不希望删除“噪音回答”。我希望他能理解我正在帮助这些可怜的家伙,所以没有人能看出他们完全错过了这一点。我在保护他们的声誉......

这是实现我想要的方式。但这不是一个好方法,因为xml是手工构建的,没有正确编码。

declare @colsList nvarchar(max)
set @colsList = ''
select @colsList = @colsList + '+ ''<' + COLUMN_NAME + '>'' + Isnull(cast( [' + COLUMN_NAME + '] as nvarchar(max)),'''') + ''</' + COLUMN_NAME + '>'' ' 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME = 'SampleTable';

select @colsList = stuff(@colsList,1,1,'');
exec('select colsValues=cast(' + @colsList + ' as xml) from SampleTable');

3 个答案:

答案 0 :(得分:18)

嗯越简单越快越好。

select d=(select a.* for xml path('r'),type,elements absent)
from MyTable a

答案 1 :(得分:9)

最简单的方法是使用它:

SELECT (SELECT T.* FOR XML RAW)
FROM MyTable T

或者如果您想要更多地控制XML结构,您应该使用:

SELECT (SELECT T.* FROM (SELECT T.*) T FOR XML AUTO)
FROM MyTable T

答案 2 :(得分:1)

修改

要为每行生成XML列 ,您可以使用以下

-- this is a poor cousin of a proper sanitize function. Add to it whatever you need
-- to cater for your column names that will be invalid XML tag names
-- example below only removes spaces (xml node names cannot contain spaces)
create function dbo.sanitize(@colname sysname) returns sysname
as begin
return replace(@colname,' ', '')
end
GO

-- test table
create table [test table](i int, s varchar(max), [d t] datetime)
insert [test table] select 1, 'abc', getdate()
insert [test table] select 2, 'def', getutcdate()
insert [test table] select 3, 'g', getdate()+10
insert [test table] select 4, 'hij', getutcdate()+20
GO

-- the dynamic SQL to return each row as an single XML column
declare @tablename sysname set @tablename = 'test table';
declare @colsList nvarchar(max)
select @colsList = isnull(@colsList+',','') +
    QuoteName(column_name) + ' as ' +
    dbo.sanitize(column_name)
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME = @tablename;

select @colsList = '
    select (select ' + @colslist + ' for xml path (''cols''))
    from ' + quotename(@tablename)
--print @colslist
exec(@colslist);

作为整个表的单个XML文档

只需使用FOR XML,并指定“cols”的路径

declare @tbl table (col1 int, col2 int)
insert @tbl values (1,1)
insert @tbl values (2,2)
insert @tbl values (3,3)
insert @tbl values (4,4)

-- you can use just the part below here
select col1, col2
from @tbl
for xml path('cols')

输出

<cols>
  <col1>1</col1>
  <col2>1</col2>
</cols>
<cols>
  <col1>2</col1>
  <col2>2</col2>
</cols>
<cols>
  <col1>3</col1>
  <col2>3</col2>
</cols>
<cols>
  <col1>4</col1>
  <col2>4</col2>
</cols>

请注意,对于XML,格式和空格具有无固有含义。所以要么你想要一个包含多行(类似于XML)的VARCHAR结果,要么你想要XML - 选择一个。