К сожалению - то, что вы пытаетесь сделать, невозможно.Две основные проблемы (если у вас есть свобода действий, возможно, есть решение).
Во-первых, ни один из параметров XML в SQL (даже не используя EXPLICIT) допускает динамическое именование узлов.Вы можете использовать атрибут <tn id="TABLE_A" />
или значение <tn>TABLE_A</tn>
, но вы не можете получить <TABLE_A>
, если не установите его жестко.
Типы XML допускают вложение / подзапросы.
SELECT V1.tbname
,(SELECT V2.colname FROM testtable V2
WHERE V1.tbname = V2.tbname FOR XML PATH(''), ELEMENTS, TYPE)
FROM testtable V1
FOR XML AUTO, ROOT('datatable')
Ваша вторая проблема связана с тем фактом, что ваши данные денормализованы.Нет никакого способа получить уникальный список таблиц (вы не можете использовать DISTINCT выше, потому что SQL не может сравнивать типы XML).Это ограничивает то, что вы можете сделать за один проход (оператор).
Если вы хотите использовать временную таблицу (или переменную таблицы), вы можете выбрать отдельный список имен таблиц, а затем объединить его симена столбцов, как в приведенном примере (сначала выполните следующее и замените внешнее from на @tblist).
DECLARE @tblist TABLE (tbname varchar(20))
INSERT INTO @tblist SELECT DISTINCT tbname FROM testtable
Возвращает это:
<datatable>
<V1 tbname="TBA">
<colname>COL 1</colname>
<colname>COL 2</colname>
</V1>
<V1 tbname="TBB">
<colname>COL 1</colname>
<colname>COL 2</colname>
</V1>
</datatable>
Вы также должны захотеть, чтобы узлы имен вашей таблицы были атрибутами (вы всегда можете запустить GREP или простую замену впоследствии, чтобы сделатьузел будет оценен) он был бы закрыт, если бы не тот формат, который вы ищете.
Извините - это, вероятно, не то, что вы хотите услышать.Но за пару простых шагов это можно сделать.Просто не напрямую из SQL Server в одном выражении.