powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / XML в таблицу/тупл с динамическим созданием колонок
14 сообщений из 14, страница 1 из 1
XML в таблицу/тупл с динамическим созданием колонок
    #39979574
Etoneja
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Подскажите, пожалуйста, можно ли сделать так, как хочу. Или, возможно, для этого есть лучшее решение.

Microsoft SQL Server 2008 R2

Приложение (веб-сервис) взаимодействует с sql-сервером через вызов процедур. Есть таблица на 100+ колонок, в которую нужно вставлять данные. Описывать каждое поле отдельным параметром показалось непрактичным, поэтому передаю параметром в хранимую процедуру xml. Логика процедуры - вставка с условием.

Хорошо бы подошло какое-то решение, при котором можно было бы преобразовывать xml-документ в таблицу/тупл с динамическим созданием колонок (названий, типов).

Сейчас есть две трудности:
а) динамическое создание колонок с сохранением оригинального названия (имя ноды);
б) динамическая спецификация типа.

Поиски в сети пока не приводят к решению.
Был бы рад услышать любые советы, рекомендации, замечания по озвученному вопросу.

Упрощенный пример:

XML и его разбор в ручном режиме:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
DECLARE @XML xml
SET @XML = '<root>
	<tax_office_legal>7811</tax_office_legal>
	<city_type>г</city_type>
	<settlement_fias_id></settlement_fias_id>
	<settlement_type_full></settlement_type_full>
	<qc_complete></qc_complete>
	<house_type_full>дом</house_type_full>
	<area_with_type></area_with_type>
	<square_meter_price></square_meter_price>
	<house>120</house>
</root>'

SELECT 
    x.Rec.query('./tax_office_legal').value('.', 'varchar(150)') AS 'tax_office_legal',
    x.Rec.query('./city_type').value('.', 'varchar(150)') AS 'city_type',
	x.Rec.query('./fias_level').value('.', 'smallint') as 'fias_level'
FROM @xml.nodes('/root') as x(Rec)



Результат:


Ожидание:
Подобный результат, но без ручной спецификации каждой колонки.
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979585
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Etoneja,

зачем? Храните XML в колонке.
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979592
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Etoneja
можно было бы преобразовывать xml-документ в таблицу/тупл с динамическим созданием колонок (названий, типов).
Только для того, чтобы иметь возможность написать insert into MyTable select *?

ЗЫ: Почитайте про параметры табличного типа.
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979601
Etoneja
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов, наверное, можно было бы рассмотреть такой вариант, но
а) на таблице различные ограничения: как по сингл, так и по мультиполям;
б) на таблицу джоинится всякое разное;
в) так, в целом, не принято. То есть, сейчас я рассматриваю вариант, как было бы удобнее вставлять мне, а есть еще и удобство других, у которых уже свои селекты.
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979604
Etoneja
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm, почти простой инсерт, но некоторая логига все же, возможно, потребуется позже. Тогда вы, наверное, скажете про триггер на вставку, и я бы это рассмотрел, но процедура вызывается не из ms sql пространства. Поэтому мне кажется, что табличный параметр не подойдет. Или мне все же надо еще почитать про них?

upd: извините за мультипост, не сразу заметил кнопку "редактировать".

upd2: если в меру простого решения для задачи нет, то я тоже хотел бы услышать это как мнение. Пока, пытаясь что-то придумать, я все еще рассматриваю "хардкод" на все поля.
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979609
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Etoneja
процедура вызывается не из ms sql пространства
Значение табличного параметра можно и из клиента задавать, если он это умеет.

В принципе, если дополните xml признаком стрпока/число, можно будет достаточно просто сгенерировать инструкцию insert.
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979613
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Etoneja,

надо придумать какое-то иное решение, в таком случае. Таблиц с переменным количеством колонок не бывает в реляционной механике. Если Вы практикуете ООП, то можете создать в методе конструктор запросов на базе конфигурации, которая будет храниться на сервере, например.
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979614
Etoneja
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm, структурой и составом входного xml я полностью управляю, поэтому могу сделать его любым. Еще поиграюсь, но пока не вижу простого способа вставки без спецификации каждого поля.

Есть вариант: преобразовывать xml к таблице с одной колонкой, где будут значения всех нод. Далее транспонировать это и уже вставлять, но это как-то "грязно" и накладывает очень большие требования на соблюдение порядка.


Владислав Колосов, прямые запросы невозможны по архитектуре, только вызов процедур. Количество полей постоянно, а не переменно. Только их много, что делает неудобным ручную спецификацию в процедуре.
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979624
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Etoneja,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
declare @xml xml
set @xml = '<root>
	<tax_office_legal>7811</tax_office_legal>
	<city_type type = "string">г</city_type>
	<settlement_fias_id></settlement_fias_id>
	<settlement_type_full></settlement_type_full>
	<qc_complete></qc_complete>
	<house_type_full type = "string">дом</house_type_full>
	<area_with_type></area_with_type>
	<square_meter_price></square_meter_price>
	<house>120</house>
</root>';

declare @sql varchar(max);

with t as
(
 select
  row_number() over (order by 1/0) as rn,
  t.n.value('local-name(.)', 'varchar(100)') as field_name,
  nullif(t.n.value('.', 'varchar(100)'), '') as field_value,
  case when t.n.value('@type', 'varchar(100)') = 'string' then 1 else 0 end as is_string
 from
  @xml.nodes('/root/*') t(n)
)
select
 @sql = 
 'insert into MyTable ' + 
 '(' + stuff(a.x.value('.', 'varchar(max)'), 1, 2, '') + ')' +
 ' values ' +
 '(' + stuff(b.x.value('.', 'varchar(max)'), 1, 2, '') + ');'
from
 (select ', ' + quotename(field_name) from t order by rn for xml path(''), type) a(x) cross apply
 (
  select
   ', ' + 
   case
    when field_value is null then 'null'
    when is_string = 1 then quotename(field_value, '''')
    else field_value
   end
  from
   t
  order by
   rn
  for xml path(''), type
 )b(x);

 print @sql;
 exec(@sql);
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979636
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Etoneja
Количество полей постоянно, а не переменно. Только их много, что делает неудобным ручную спецификацию в процедуре.


Но это же делается один раз всего. И в любом случае вы в INSERT специфицируете эти поля.

Иначе, если я правильно понимаю задачу, вы хотите передать (где то сформированный) кусок текста в процедуру, потом его распарсить его на значения и вставить. Но зачем а) создавать xml, б) потом заставлять сервер его разбирать?

Etoneja
в таблицу/тупл с динамическим созданием колонок

Окей, будет у вас временная таблица/табличная переменная созданная динамически из xml. А дальше то надо вставлять в обычную таблицу и как это у вас реализовано? Динамически?
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979674
Etoneja
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm,

Интересный ход мыслей. Решение рабочее и задачу, определенную в стартовом сообщении топика, решает.
Спасибо, возьму идею на заметку. Пока не вижу причин не использовать, хотя надо будет "поиграться" со специальными символами и придумать более-менее элегатный способ для обработки нескольких строк в исходном xml.


PizzaPizza

Иначе, если я правильно понимаю задачу, вы хотите передать (где то сформированный) кусок текста в процедуру, потом его распарсить его на значения и вставить. Но зачем а) создавать xml, б) потом заставлять сервер его разбирать?

Не совсем так. Задача другими словами: взаимодействие с объектами БД через RPC. Когда параметров становится много с ними уже неудобно работать по ряду причин. Поэтому все эти параметры упаковываются в xml (что-то вроде примитивного ООП - его можно и провалидировать в приложении). Вопрос заключался в том, как этот xml, переданный параметром в хранимую процедуру, динамично разобрать. Возможно, это "велосипед", но других вариантов не придумал.

Пользователь invm предложил решение не преобразовывать это в тупл/таблицу, как я изначально хотел, а склеивать и выполнять в виде запроса. Это, может быть, не очень "чисто", но дает ту самую динамичность.
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979689
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Etoneja,

Но про динамичность не понятно. Добавление новых тегов в xml автоматически не добавит их в таблицу базы.

Динамическое в плане
EtonejaЕсть таблица на 100+ колоноки по этому вам нужна возможность вставлять то 50 значений, то 100, то 2 ?
Я бы очень подумал про дизайн базы в данном случае.

Опять же, если вы пишете на С# то там можно создать "таблицу" (пользовательский тип данных) прям в приложении и передать в процедуру. И из неё сделать SELECT * FROM @пользовательская_табличная_переменная
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979828
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Etoneja,

invm Вам нарисовал конструктор запроса, но этот конструктор лучше организовать на стороне сервиса. Формально задачи слоя приложений должен решать слой приложений. Т.е. разработчик веб-приложения решает понятную ему задачу согласно полученной спецификации таблицы, а разработчик БД решает задачи, связанные с размещением этих данных.
...
Рейтинг: 0 / 0
XML в таблицу/тупл с динамическим созданием колонок
    #39979923
godsql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PizzaPizza
Etoneja,

Но про динамичность не понятно. Добавление новых тегов в xml автоматически не добавит их в таблицу базы.

Динамическое в плане
EtonejaЕсть таблица на 100+ колонок
и по этому вам нужна возможность вставлять то 50 значений, то 100, то 2 ?
Я бы очень подумал про дизайн базы в данном случае.


В одном из продуктов морского млекопитающего так был реализован сервис отчетности: Таблица на н-цать фиксированных столбцов, каждый из которых ассоциировался с полем генератора отчета.
Данные загонялись в нужные поля с ID процесса, который вызывал формирование отчета
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / XML в таблицу/тупл с динамическим созданием колонок
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]