Обновление SQL Server Имя столбца XML-узел - PullRequest
0 голосов
/ 01 октября 2019

Я сохранил свои данные в формате XML на сервере SQL, таким образом

**<Column Name="GROSS" DataType="float" Value="939760" />**

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

Ниже приведены скриншоты моей базы данных:

Представление таблицы

table view screen 1

XML view

XML View screen 2

Это то, что я пробовал, но оно только изменило значение, оно не переименовало имя столбца.

update Aquara7bc772839.EmpTransaction set TransactionFieldDetails.modify('replace value of (/PayDetails/Column[@Name="LEV_ENCASHRATE"]/@Value)[1] with "796.00"') WHERE Id = 276620;

Need to do screen

Я выделил имена своих столбцов в приведенной выше ссылке на изображение, пожалуйста, отметьте, я хочу удалить или переименовать один столбец.

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Вы можете использовать XML.modify () метод с удалить узел инструкция ...

declare @EmpTransaction table (
  Id int not null,
  TransactionFieldDetails xml
);
insert @EmpTransaction values (
  276620,
  N'<PayDetails>
<Column Name="GROSS" DataType="float" Value="939760" />
<Column Name="GROSS" DataType="float" Value="939760" />
</PayDetails>'
);

update @EmpTransaction
set TransactionFieldDetails.modify('delete /PayDetails/Column[@Name="GROSS"][2]')
where Id = 276620;

select * from @EmpTransaction;

Что дает вам ...

<PayDetails>
  <Column Name="GROSS" DataType="float" Value="939760" />
</PayDetails>

Обратите внимание, что индекс узла основан на 1, то есть: Column[@Name="GROSS"][1] удалит первый узел GROSS, Column[@Name="GROSS"][2] удалит второй узел GROSS.

Относительно того, как вы получили дваВо-первых, значения GROSS ... независимо от того, что для вас создан XML, вероятно, дважды будет отображаться столбец GROSS.

0 голосов
/ 01 октября 2019

Для вашего следующего вопроса: Пожалуйста, не размещайте фотографии. Лучше всего было предоставить MCVE ( автономный образец для воспроизведения вашей проблемы).

Вы можете попробовать что-то вроде этого:

Это такой автономный образец

DECLARE @mockupTable TABLE(ID INT IDENTITY, YourXml XML);
INSERT INTO @mockupTable VALUES
(N'<PayDetails>
     <Column Name="blah" DataType="string" Value="Some blah" />
     <Column Name="GROSS" DataType="float" Value="1.1" />
     <Column Name="Another" DataType="string" Value="One more" />
     <Column Name="GROSS" DataType="float" Value="1.2" />
   </PayDetails>')
,(N'<PayDetails>
     <Column Name="blah" DataType="string" Value="Some blah" />
     <Column Name="GROSS" DataType="float" Value="2.0" />
     <Column Name="Another" DataType="string" Value="One more" />
     <Column Name="GROSS" DataType="float" Value="2.0" />
   </PayDetails>');

- Этот запрос сначала проверит наличие различных значений для GROSS в одном XML. Это может быть причиной для того, чтобы присмотреться, прежде чем удалять их.

SELECT t.ID
      ,t.YourXml
FROM @mockupTable t
WHERE t.YourXml.value('count(distinct-values(/PayDetails/Column[@Name="GROSS"]/@Value))','int')>1;

- И этот оператор будет возвращать каждый <Column> только один раз для имени (всегда первый в своем роде)

UPDATE @mockupTable SET YourXml=YourXml.query(N'
                                               <PayDetails>
                                               {
                                                 for $elmt in distinct-values(/PayDetails/Column/@Name)
                                                 return /PayDetails/Column[@Name=$elmt][1]
                                               }
                                               </PayDetails>
                                               ');

- Проверить вывод

SELECT * FROM @mockupTable

Идея вкратце:

С помощью Xpath /PayDetails/Column[@Name="GROSS"] мы уменьшаем наблюдаемый набор до столбцов, где атрибут Name равно GROSSdistinct-values() - это функция XQuery, возвращающая каждое значение в списке только один раз. Таким образом, мы можем использовать count(), чтобы проверить, существуют ли различные значения для GROSS в одном XML.

* UPDATE использует возможности FLWOR XQuery. Мы снова используем distinct-values, чтобы получить все значения для Name в пределах <Column>. Затем мы возвращаем только первое (см. [1]) для каждого имени.

ОБНОВЛЕНИЕ: проверка на дублированные элементы

С помощью этого запроса вы можете выполнить всю таблицу для поиска любого неуникальное имя столбца для XML:

SELECT t.YourXml.query(N'
                        for $elmt in distinct-values(/PayDetails/Column/@Name)
                        return <NameCount Name="{$elmt}" Count="{count(/PayDetails/Column[@Name=$elmt])}"/>
                        ').query('/NameCount[@Count>1]')
FROM @mockupTable t;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...