Поделиться через


replace value of (XML DML)

Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure

Обновляет значение узла в документе.

Синтаксис

replace value of Expression1
with Expression2

Аргументы

Expression1

Определяет узел, значение которого должно быть обновлено. Оно должно определять только один узел. Таким образом, Expression1 должно быть статическим одноэлементным выражением. Если XML-код типируется, тип узла должен быть простым типом. Выбор нескольких узлов вызовет ошибку. Если Expression1 возвращает пустую последовательность, то замены значения не произойдет и не будет возвращено сообщение об ошибке. Expression1 должно возвращать одиночный элемент с простым типизированным содержимым (списком или атомарными типами), текстовым узлом или узлом атрибута. Expression1 не может быть типом объединения, сложным типом, инструкцией по обработке, узлом документа или узлом комментария, иначе возникнет ошибка.

Expression2

Определяет новое значение узла. Это может быть выражение, которое возвращает простой узел типа, так как data() используется неявно. Если значение является списком значений, update инструкция заменяет старое значение списком. При изменении типизированного экземпляра XML Выражение2 должно быть таким же типом или подтипом Expression1. Иначе возвращается ошибка. При изменении нетипизированного экземпляра XML Выражение2 должно быть выражением, которое можно атомизировать. Иначе возвращается ошибка.

Примеры

Примеры кода Transact-SQL в этой статье используют AdventureWorks2022 базу данных или AdventureWorksDW2022 пример базы данных, которую можно скачать с домашней страницы примеров и проектов сообщества Microsoft SQL Server.

В следующих примерах инструкции replace value of XML DML показано, как обновлять узлы в XML-документе.

А. Замена значений в экземпляре XML

В следующем примере экземпляр документа сначала присваивается переменной типа xml. replace value of Затем инструкции XML DML обновляют значения в документе.

DECLARE @myDoc XML;

SET @myDoc = '<Root>
<Location LocationID="10"
            LaborHours="1.1"
            MachineHours=".2" >Manufacturing steps are described here.
<step>Manufacturing step 1 at this work center</step>
<step>Manufacturing step 2 at this work center</step>
</Location>
</Root>';

SELECT @myDoc;

-- update text in the first manufacturing step
SET @myDoc.modify('
  replace value of (/Root/Location/step[1]/text())[1]
  with "new text describing the manu step"
');

SELECT @myDoc;

-- update attribute value
SET @myDoc.modify('
  replace value of (/Root/Location/@LaborHours)[1]
  with "100.0"
');

SELECT @myDoc;

Обновляемый адресат должен быть не более чем одним узлом, который явно указывается в выражении пути при добавлении [1] в конце выражения.

B. Используйте выражение if для определения значения замены

Выражение можно указать if в Expression2 replace value of инструкции, как показано в следующем примере. Выражение1 определяет LaborHours атрибут из первого рабочего центра. Expression2 использует if выражение для определения нового значения атрибута LaborHours .

DECLARE @myDoc XML;
SET @myDoc = '<Root>
<Location LocationID="10"
            LaborHours=".1"
            MachineHours=".2" >Manu steps are described here.
<step>Manufacturing step 1 at this work center</step>
<step>Manufacturing step 2 at this work center</step>
</Location>
</Root>';

--SELECT @myDoc
SET @myDoc.modify('
  replace value of (/Root/Location[1]/@LaborHours)[1]
  with (
       if (count(/Root/Location[1]/step) > 3) then
         "3.0"
       else
          "1.0"
      )
');

SELECT @myDoc;

C. Обновление XML, хранящегося в нетипизированном XML-столбце

Следующий пример обновляет XML, сохраненный в столбце:

DROP TABLE T;
GO

CREATE TABLE T (i INT, x XML);
GO

INSERT INTO T
VALUES (
    1,
    '<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features>
  <Warranty>1 year parts and labor</Warranty>
  <Maintenance>3 year parts and labor extended maintenance is available</Maintenance>
</Features>
</ProductDescription>
</Root>'
);
GO

-- verify the current <ProductDescription> element
SELECT x.query(' /Root/ProductDescription')
FROM T;

-- update the ProductName attribute value
UPDATE T
SET x.modify('
  replace value of (/Root/ProductDescription/@ProductName)[1]
  with "New Road Bike" ');

-- verify the update
SELECT x.query(' /Root/ProductDescription');
FROM T

D. Обновление XML, хранящегося в типизированном XML-столбце

Этот пример заменяет значения в документе производственных команд, сохраненном в типизированном столбце XML.

В примере сначала создается таблица (T) с типизированным XML-столбцом в AdventureWorks2022 базе данных. Затем вы копируете xml-экземпляр инструкций производства из Instructions столбца таблицы ProductModel в таблицу T. Затем вставки применяются к XML в таблице T.

USE AdventureWorks2022;
GO

DROP TABLE T;
GO

CREATE TABLE T (
    ProductModelID INT PRIMARY KEY,
    Instructions XML(Production.ManuInstructionsSchemaCollection)
);
GO

INSERT T
SELECT ProductModelID, Instructions
FROM Production.ProductModel
WHERE ProductModelID = 7;
GO

--insert a new location - <Location 1000/>.
UPDATE T
SET Instructions.modify('
  declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
insert <MI:Location LocationID="1000"  LaborHours="1000"  LotSize="1000" >
           <MI:step>Do something using <MI:tool>hammer</MI:tool></MI:step>
         </MI:Location>
  as first
  into (/MI:root)[1]
');
GO

SELECT Instructions
FROM T;
GO

-- Now replace manu. tool in location 1000
UPDATE T
SET Instructions.modify('
  declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
  replace value of (/MI:root/MI:Location/MI:step/MI:tool)[1]
  with "screwdriver"
');
GO

SELECT Instructions
FROM T;

-- Now replace value of lot size
UPDATE T
SET Instructions.modify('
  declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
  replace value of (/MI:root/MI:Location/@LotSize)[1]
  with 500 cast as xs:decimal ?
');
GO

SELECT Instructions
FROM T;

В этом примере используется cast при замене LotSize значения. cast требуется, если значение должно иметь определенный тип. В этом примере, если 500 это значение, явное приведение не требуется.