tsql: преобразовать столбцы в столбец xml, по одному xml на строку - PullRequest
4 голосов
/ 11 февраля 2011

Пример того, что у меня есть:

таблица: (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 ]

18 голосов
/ 12 февраля 2011

Ну, чем проще, тем лучше.

select d=(select a.* for xml path('r'),type,elements absent)
from MyTable a
9 голосов
/ 06 марта 2011

Самый простой способ - использовать это:

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

Или, если вы хотите больше контроля над структурой XML, вам следует использовать:

SELECT (SELECT T.* FROM (SELECT T.*) T FOR XML AUTO)
FROM MyTable T
1 голос
/ 11 февраля 2011

РЕДАКТИРОВАТЬ

Чтобы создать столбец 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 форматирование и пробелы не имеют никакого присущегосмысл .Так что либо вы хотите получить результат VARCHAR с несколькими строками (напоминающий XML), либо вы хотите XML - выберите одну.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...