insert (XML DML)
Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure
Вставляет один или несколько узлов, идентифицируемых выражением Expression1, в качестве дочерних узлов или одноуровневых элементов с общим родителем для узла, идентифицируемого выражением Expression2.
Синтаксис
insert Expression1 (
{as first | as last} into | after | before
Expression2
)
Аргументы
Expression1
Идентифицирует один или несколько вставляемых узлов. Это может быть постоянный экземпляр XML; ссылка на типизированный тип данных XML той же коллекции XML-схем, к которой применяется метод изменения; нетипизированный тип данных XML, использующий изолированную функцию sql:column()/sql:variable(); или выражение XQuery. Результатом выражения может быть узел, в том числе текстовый, или упорядоченная последовательность узлов. Корневой узел (/) не может быть результатом выражения. Если результатом выражения является значение или последовательность значений, то такие значения вставляются в качестве одиночного текстового узла, в котором все значения разделены пробелами. Если несколько узлов указаны как постоянные, они заключаются в скобки и разделяются запятыми. Разнородные последовательности, например, последовательность элементов, атрибутов или значений, вставлять нельзя. Если результатом выражения Expression1 является пустая последовательность, вставка не выполняется, и никакие ошибки не возвращаются.
into
Узлы, определяемые выражением Expression1, вставляются в качестве прямых потомков (дочерних узлов) узла, определяемого выражением Expression2. Если у узла в выражении Expression2 уже есть один или более дочерних узлов, то необходимо использовать ключевые слова as first или as last, чтобы указать, где следует добавить новый узел. Они означают, соответственно, добавление в начало или в конец списка потомков. Ключевые слова as first и as last при вставке атрибутов игнорируются.
после
Узлы, определяемые выражением Expression1, вставляются в качестве элементов с общим родителем непосредственно после узла, определяемого выражением Expression2. При вставке атрибутов не может использоваться ключевое слово after. Например, его нельзя использовать для вставки конструктора атрибута или для возвращения атрибута из запроса XQuery.
before
Узлы, определяемые выражением Expression1, вставляются в качестве элементов с общим родителем непосредственно перед узлом, определяемым выражением Expression2. При вставке атрибутов не может использоваться ключевое слово before. Например, его нельзя использовать для вставки конструктора атрибута или для возвращения атрибута из запроса XQuery.
Expression2
Идентифицирует узел. Вставка узлов, определяемых выражением Expression1, выполняется относительно узла, определяемого выражением Expression2. Это может быть выражение XQuery, возвращающее ссылку на узел, существующий в документе, к которому в данный момент производится обращение. Если возвращается более одного узла, то операция вставки завершается неудачно. Если результатом выражения Expression2 является пустая последовательность, то вставка не производится и ошибки не возвращаются. Если выражение Expression2 статически не является одноэлементным множеством, то возвращается статическая ошибка. Выражение Expression2 не может представлять собой инструкцию по обработке, комментарий или атрибут. Обратите внимание, что выражение Expression2 должно представлять собой ссылку на существующий узел в документе, а не на конструируемый узел.
Примеры
А. Вставка узлов элементов в документ
В следующем примере показана вставка элементов в документ. Сначала XML-документ присваивается переменной типа xml. Затем с помощью нескольких XML-инструкций DML insert демонстрируется вставка узлов элементов в документ. После каждой операции вставки с помощью инструкции SELECT отображается результат.
USE AdventureWorks;
GO
DECLARE @myDoc XML;
SET @myDoc = '<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features>
</Features>
</ProductDescription>
</Root>' ;
SELECT @myDoc;
-- insert first feature child (no need to specify as first or as last)
SET @myDoc.modify('
insert <Maintenance>3 year parts and labor extended maintenance is available</Maintenance>
into (/Root/ProductDescription/Features)[1]') ;
SELECT @myDoc ;
-- insert second feature. We want this to be the first in sequence so use 'as first'
SET @myDoc.modify('
insert <Warranty>1 year parts and labor</Warranty>
as first
into (/Root/ProductDescription/Features)[1]
') ;
SELECT @myDoc ;
-- insert third feature child. This one is the last child of <Features> so use 'as last'
SELECT @myDoc
SET @myDoc.modify('
insert <Material>Aluminium</Material>
as last
into (/Root/ProductDescription/Features)[1]
')
SELECT @myDoc ;
-- Add fourth feature - this time as a sibling (and not a child)
-- 'after' keyword is used (instead of as first or as last child)
SELECT @myDoc ;
SET @myDoc.modify('
insert <BikeFrame>Strong long lasting</BikeFrame>
after (/Root/ProductDescription/Features/Material)[1]
') ;
SELECT @myDoc;
GO
Заметьте, что в разнообразных выражениях путей в данном примере в качестве требования к статическому вводу указывается «[1]». Это позволяет гарантированно указать отдельный целевой узел.
B. Вставка нескольких элементов в документ
В следующем примере документу сначала назначается переменная типа xml. Затем последовательность из двух элементов, представляющих функции продукта, назначается второй переменной типа xml. Эта последовательность затем вставляется в первую переменную.
USE AdventureWorks;
GO
DECLARE @myDoc XML;
SET @myDoc = N'<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features> </Features>
</ProductDescription>
</Root>';
DECLARE @newFeatures xml;
SET @newFeatures = N'<Warranty>1 year parts and labor</Warranty>
<Maintenance>3 year parts and labor extended maintenance is available</Maintenance>';
-- insert new features from specified variable
SET @myDoc.modify('
insert sql:variable("@newFeatures")
into (/Root/ProductDescription/Features)[1] ')
SELECT @myDoc;
GO
C. Вставка атрибутов в документ
В следующем примере показана вставка атрибутов в документ. Сначала документ заносится в переменную типа xml. Затем используется серия XML-инструкций DML insert для вставки атрибутов в документ. После каждой операции вставки с помощью инструкции SELECT отображается результат.
USE AdventureWorks;
GO
DECLARE @myDoc XML;
SET @myDoc =
'<Root>
<Location LocationID="10" >
<step>Manufacturing step 1 at this work center</step>
<step>Manufacturing step 2 at this work center</step>
</Location>
</Root>' ;
SELECT @myDoc;
-- insert LaborHours attribute
SET @myDoc.modify('
insert attribute LaborHours {".5" }
into (/Root/Location[@LocationID=10])[1] ');
SELECT @myDoc;
-- insert MachineHours attribute but its value is retrieved from a sql variable @Hrs
DECLARE @Hrs FLOAT;
SET @Hrs =.2;
SET @myDoc.modify('
insert attribute MachineHours {sql:variable("@Hrs") }
into (/Root/Location[@LocationID=10])[1] ');
SELECT @myDoc;
-- insert sequence of attribute nodes (note the use of ',' and ()
-- around the attributes.
SET @myDoc.modify('
insert (
attribute SetupHours {".5" },
attribute SomeOtherAtt {".2"}
)
into (/Root/Location[@LocationID=10])[1] ');
SELECT @myDoc;
GO
D. Вставка узла с комментарием
В этом запросе XML-документ сначала присваивается переменной типа xml. Затем для вставки узла с комментарием после первого элемента <step
> используется язык XML DML.
USE AdventureWorks;
GO
DECLARE @myDoc XML;
SET @myDoc =
'<Root>
<Location LocationID="10" >
<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('
insert <!-- some comment -->
after (/Root/Location[@LocationID=10]/step[1])[1] ');
SELECT @myDoc;
GO
Е. Вставка инструкции по обработке
В этом запросе XML-документ сначала присваивается переменной типа xml. Затем используется ключевое слово языка XML DML для вставки инструкции по обработке в начало документа.
USE AdventureWorks;
GO
DECLARE @myDoc XML;
SET @myDoc =
'<Root>
<Location LocationID="10" >
<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('
insert <?Program = "Instructions.exe" ?>
before (/Root)[1] ') ;
SELECT @myDoc ;
GO
F. Вставка данных с помощью раздела CDATA
При вставке текста, содержащего недопустимые в XML символы, например < или >, можно использовать разделы CDATA для вставки данных, как показано в следующем запросе. В запросе указывается раздел CDATA, но добавляется он в качестве текстового узла, в котором недопустимые символы преобразуются в сущности. Например, <
сохраняется как <
.
USE AdventureWorks;
GO
DECLARE @myDoc XML;
SET @myDoc =
'<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features> </Features>
</ProductDescription>
</Root>' ;
SELECT @myDoc ;
SET @myDoc.modify('
insert <![CDATA[ <notxml> as text </notxml> or cdata ]]>
into (/Root/ProductDescription/Features)[1] ') ;
SELECT @myDoc ;
GO
Запрос вставляет текстовый узел в элемент <Features
>:
<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features> <notxml@gt; as text </notxml> or cdata </Features>
</ProductDescription>
</Root>
G. Вставка текстового узла
В этом запросе XML-документ сначала присваивается переменной типа xml. Затем для вставки текстового узла в качестве первого дочернего узла элемента <Root
> используется язык XML DML. Для указания текста используется текстовый конструктор.
USE AdventureWorks;
GO
DECLARE @myDoc XML;
SET @myDoc = '<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features>
</Features>
</ProductDescription>
</Root>'
SELECT @myDoc;
SET @myDoc.modify('
insert text{"Product Catalog Description"}
as first into (/Root)[1]
');
SELECT @myDoc;
H. Вставка нового элемента в нетипизированный XML-столбец
В следующем примере язык XML DML применяется для обновления экземпляра XML, хранящегося в столбце типа xml:
USE AdventureWorks;
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
-- insert a new element
UPDATE T
SET x.modify('insert <Material>Aluminium</Material> as first
into (/Root/ProductDescription/Features)[1]
');
GO
Опять же, при вставке узла элемента <Material
> выражение пути должно возвращать одну цель. Это указывается явно путем добавления [1] в конце выражения.
-- check the update
SELECT x.query(' //ProductDescription/Features')
FROM T;
GO
I. Вставка на основе инструкции с условием
В следующем примере в XML-инструкции DML insert в качестве части выражения Expression1 указывается условие IF. Если условие возвращает значение True, атрибут добавляется в элемент <WorkCenter
>.
USE AdventureWorks;
GO
DECLARE @myDoc XML;
SET @myDoc =
'<Root>
<Location LocationID="10" LaborHours="1.2" >
<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('
insert
if (/Root/Location[@LocationID=10])
then attribute MachineHours {".5"}
else ()
as first into (/Root/Location[@LocationID=10])[1] ');
SELECT @myDoc;
GO
Ниже приведен похожий пример, отличающийся только тем, что XML-инструкция DML insert вставляет элемент в документ, если условие возвращает значение True. То есть в случае, если элемент <WorkCenter
> содержит два или менее дочерних элементов <step
>.
USE AdventureWorks;
GO
DECLARE @myDoc XML;
SET @myDoc =
'<Root>
<Location LocationID="10" LaborHours="1.2" >
<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('
insert
if (count(/Root/Location/step) <= 2)
then element step { "This is a new step" }
else ()
as last into (/Root/Location[@LocationID=10])[1] ');
SELECT @myDoc;
GO
Результат:
<Root>
<WorkCenter WorkCenterID="10" LaborHours="1.2">
<step>Manufacturing step 1 at this work center</step>
<step>Manufacturing step 2 at this work center</step>
<step>This is a new step</step>
</WorkCenter>
J. Вставка узлов в типизированный XML-столбец
В данном примере выполняется вставка элемента и атрибута в производственные инструкции в формате XML, которые хранятся в типизированном столбце типа xml.
В примере сначала создается таблица (T) с типизированным столбцом типа xml в базе данных AdventureWorks. Затем копируются производственные инструкции экземпляра XML из столбца Instructions в таблице ProductModel в таблицу T. После этого вставленные данные применяются к XML в таблице T.
USE AdventureWorks;
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
SELECT Instructions
FROM T;
-- now insertion begins
--1) insert a new manu. Location. The <Root> specified as
-- expression 2 in the insert() must be singleton.
UPDATE T
SET Instructions.modify('
declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
insert <MI:Location LocationID="1000" >
<MI:step>New instructions go here</MI:step>
</MI:Location>
as first
into (/MI:root)[1]
') ;
SELECT Instructions
FROM T ;
-- 2) insert attributes in the new <Location>
UPDATE T
SET Instructions.modify('
declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
insert attribute LaborHours { "1000" }
into (/MI:root/MI:Location[@LocationID=1000])[1] ');
GO
SELECT Instructions
FROM T ;
GO
--cleanup
DROP TABLE T ;
GO
См. также
Сравнение типизированного и нетипизированного XML
Создание экземпляров данных XML
Методы для типа данных XML
Язык обработки XML-данных (XML DML)