Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Задание:
- -- - написать скрипт на MS SQL, который переставляет атрибуты (в алфавитном
- -- порядке, начиная со второго места, на первом месте должен быть ключевой атрибут)
- -- (ключевой атрибут для каждого тега задается в отдельной таблице, как
- -- метаданные)
- -- Этот скрипт должен применяться для заданных XML полей в таблице и, как
- -- вариант, для все строк таблицы LOGU
- -- xml, в котором надо упорядочить атрибуты
- declare @xml xml = '<root1 id = "2" a = "a" zzz="d" >
- <test d = "b" c = "c" id="1" a = "a"/>
- <test w = "c" x122 = "b" x44 = "a" id="v"/>
- </root1>';
- -- Добавляем фейковый корневой элемент для корректной обработки исходных корневых узлов
- set @xml = @xml.query('<newRoot> { for $item in * return $item } </newRoot>');
- -- Для каждого тега выставляем его ключевой атрибут
- declare @KeyAttributesForTags table(node nvarchar(MAX), attr nvarchar(MAX));
- insert into @KeyAttributesForTags values('root1', 'a'), ('test', 'id');
- -- Запускаем курсор по всем элементам, кроме фейковых
- declare xml_Cursor cursor for
- select n.query('.')from @xml.nodes('//*[local-name(.)!="newRoot"]') T(n)
- open xml_Cursor;
- declare @n xml;
- fetch next from xml_Cursor into @n;
- -- Пока извлечение успешно выполняется
- while @@FETCH_STATUS = 0
- BEGIN
- -- Извлекаем дополнительную информацию для обработки узлов
- declare @current_node nvarchar(max) = (select cast(n.query('local-name(.)') AS VARCHAR(MAX)) from @n.nodes('/*') T(n));
- declare @id nvarchar(max) = (select n.value('.','nvarchar(MAX)') from @n.nodes('/*/@*[1]') T(n));
- declare @parent nvarchar(max) = (select CAST(n.query('local-name(..)') AS VARCHAR(MAX))
- from @xml.nodes('//*[local-name(.) = sql:variable("@current_node")][./@*[1] = sql:variable("@id")]') T(n));
- -- Извлекаем ключевой атрибут для текущего тега
- declare @keyAttributeForTag nvarchar(max) = (select top 1 attr from @KeyAttributesForTags where node = @current_node);
- -- Извлекаем неключевые элементы во вспомогательную таблицу
- declare @NonKeyAttributes TABLE(rowNumber INT, attr NVARCHAR(MAX), val NVARCHAR(MAX));
- delete from @NonKeyAttributes;
- insert into @NonKeyAttributes select row_number() over (order by attr), attr, val from
- (select cast(n.query('local-name(.)') as varchar(MAX)), n.value('.','nvarchar(MAX)')
- from @n.nodes('/*/@*[local-name(.) != sql:variable("@keyAttributeForTag")]') T(n)) T1(attr,val);
- -- удаляем все неключевые атрибуты
- set @n.modify('delete /*/@*[local-name(.) != sql:variable("@keyAttributeForTag")]');
- -- Делаем проход по всем неключевым атрибутам
- declare @i int = (select count(*) from @NonKeyAttributes);
- while @i >= 1
- begin
- -- Вставляем вспомогательный атрибут (temp_attribute), затем заменяем его на настоящий
- declare @val nvarchar(max) = (select val from @NonKeyAttributes where rowNumber = @i);
- set @n.modify('insert attribute temp_attribute { sql:variable("@val") } into (/*)[1]');
- set @n = replace(cast(@n as nvarchar(max)), 'temp_attribute', (select attr from @NonKeyAttributes where rowNumber = @i));
- set @i-=1;
- end;
- -- Обновляем обработанную запись в xml
- set @xml.modify('delete //*[local-name(.) = sql:variable("@current_node")][./@*[1] = sql:variable("@id")]');
- SET @xml.modify('insert sql:variable("@n") into (//*)[local-name(.)=sql:variable("@parent")][1]');
- fetch next from xml_Cursor into @n;
- end;
- close xml_Cursor;
- deallocate xml_Cursor;
- set @xml = (select top 1 n.query('.') from @xml.nodes('/newRoot/*[1]') T(n));
- select @xml;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement