Advertisement
Guest User

Untitled

a guest
May 29th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
T-SQL 4.23 KB | None | 0 0
  1.  
  2. -- Задание:
  3. -- - написать скрипт на MS SQL, который переставляет атрибуты (в алфавитном
  4. -- порядке, начиная со второго места, на первом месте должен быть ключевой атрибут)
  5. --   (ключевой атрибут для каждого тега задается в отдельной таблице, как
  6. -- метаданные)
  7. --   Этот скрипт должен применяться для заданных XML полей в таблице и, как
  8. -- вариант, для все строк таблицы LOGU
  9.  
  10.  
  11. -- xml, в котором надо упорядочить атрибуты
  12. declare @xml xml = '<root1 id = "2" a = "a" zzz="d" >
  13.                         <test d = "b" c = "c" id="1" a = "a"/>
  14.                         <test w = "c" x122 = "b" x44 = "a" id="v"/>
  15.                     </root1>';
  16. -- Добавляем фейковый корневой элемент для корректной обработки исходных корневых узлов
  17. set @xml = @xml.query('<newRoot> { for $item in * return $item } </newRoot>');
  18.  
  19.  
  20. -- Для каждого тега выставляем его ключевой атрибут
  21. declare @KeyAttributesForTags table(node nvarchar(MAX), attr nvarchar(MAX));
  22. insert into @KeyAttributesForTags values('root1', 'a'), ('test', 'id');
  23.  
  24. -- Запускаем курсор по всем элементам, кроме фейковых
  25. declare xml_Cursor cursor for  
  26.     select n.query('.')from @xml.nodes('//*[local-name(.)!="newRoot"]') T(n)
  27. open xml_Cursor;
  28.  
  29. declare @n xml;
  30. fetch next from xml_Cursor into @n;  
  31.  
  32. -- Пока извлечение успешно выполняется
  33. while @@FETCH_STATUS = 0  
  34. BEGIN  
  35.     -- Извлекаем дополнительную информацию для обработки узлов
  36.     declare @current_node nvarchar(max) = (select cast(n.query('local-name(.)') AS VARCHAR(MAX)) from @n.nodes('/*') T(n));
  37.     declare @id nvarchar(max) = (select n.value('.','nvarchar(MAX)') from @n.nodes('/*/@*[1]') T(n));
  38.     declare @parent nvarchar(max) = (select CAST(n.query('local-name(..)') AS VARCHAR(MAX))
  39.                 from @xml.nodes('//*[local-name(.) = sql:variable("@current_node")][./@*[1] = sql:variable("@id")]') T(n));
  40.  
  41.     -- Извлекаем ключевой атрибут для текущего тега
  42.     declare @keyAttributeForTag nvarchar(max) = (select top 1 attr from @KeyAttributesForTags where node = @current_node);
  43.    
  44.     -- Извлекаем неключевые элементы во вспомогательную таблицу
  45.     declare @NonKeyAttributes TABLE(rowNumber INT, attr NVARCHAR(MAX), val NVARCHAR(MAX));
  46.     delete from @NonKeyAttributes;
  47.     insert into @NonKeyAttributes select row_number() over (order by attr), attr, val from
  48.     (select cast(n.query('local-name(.)') as varchar(MAX)), n.value('.','nvarchar(MAX)')
  49.         from @n.nodes('/*/@*[local-name(.) != sql:variable("@keyAttributeForTag")]') T(n)) T1(attr,val);
  50.  
  51.     -- удаляем все неключевые атрибуты
  52.     set @n.modify('delete /*/@*[local-name(.) != sql:variable("@keyAttributeForTag")]');
  53.  
  54.     -- Делаем проход по всем неключевым атрибутам
  55.     declare @i int = (select count(*) from @NonKeyAttributes);
  56.     while @i >= 1
  57.     begin
  58.         -- Вставляем вспомогательный атрибут (temp_attribute), затем заменяем его на настоящий
  59.         declare @val nvarchar(max) = (select val from @NonKeyAttributes where rowNumber = @i);
  60.         set @n.modify('insert attribute temp_attribute { sql:variable("@val") } into (/*)[1]');
  61.         set @n = replace(cast(@n as nvarchar(max)), 'temp_attribute', (select attr from @NonKeyAttributes where rowNumber = @i));
  62.  
  63.         set @i-=1;
  64.     end;
  65.  
  66.     -- Обновляем обработанную запись в xml
  67.     set @xml.modify('delete //*[local-name(.) = sql:variable("@current_node")][./@*[1] = sql:variable("@id")]');
  68.     SET @xml.modify('insert sql:variable("@n") into (//*)[local-name(.)=sql:variable("@parent")][1]');
  69.  
  70. fetch next from xml_Cursor into @n;
  71. end;
  72.  
  73. close xml_Cursor;
  74. deallocate xml_Cursor;
  75.  
  76. set @xml = (select top 1 n.query('.') from @xml.nodes('/newRoot/*[1]') T(n));
  77.  
  78. select @xml;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement