replace value of (XML DML)
Actualiza el valor de un nodo en el documento.
Sintaxis
replace value of
Expression1
with
Expression2
Argumentos
Expression1
Identifica un nodo cuyo valor se va a actualizar. Debe identificar un solo nodo. Es decir, Expression1 debe ser un singleton estático. Si el XML tiene un tipo, el tipo del nodo debe ser simple. Si se seleccionan varios nodos, se producirá un error. Si Expression1 devuelve una secuencia vacía, no se reemplazará ningún valor y no se devolverá ningún error. Expression1 debe devolver un solo elemento que incluya contenido de tipo simple (tipos de lista o atómicos), un nodo de texto o un nodo de atributo. Expression1 no puede ser un tipo de unión, un tipo complejo, una instrucción de procesamiento, un nodo de documento ni un nodo de comentario. De lo contrario, se devolverá un error.Expression2
Identifica el nuevo valor del nodo. Puede ser una expresión que devuelve un nodo de tipo simple, puesto que se utilizará data() implícitamente. Si el valor es una lista de valores, la instrucción update reemplazará el valor antiguo por la lista. Si se modifica una instancia XML con tipo, Expression2 debe ser del mismo tipo o un subtipo de Expression1. En caso contrario, se devolverá un error. Si se modifica una instancia XML sin tipo, Expression2 debe ser una expresión que se pueda atomizar. En caso contrario, se devolverá un error.
Ejemplos
Los ejemplos siguientes de la instrucción XML DML replace value of ilustran cómo se actualizan los nodos en un documento XML.
A. Reemplazar valores en una instancia XML
En el ejemplo siguiente, se asigna en primer lugar una instancia de documento a una variable de tipo xml. A continuación, las instrucciones XML DML replace value of actualizan los valores del documento.
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
Tenga en cuenta que el destino que se actualiza debe ser, como máximo, un nodo que se especifica de forma explícita en la expresión de ruta de acceso agregando un "[1]" al final de la expresión.
B. Utilizar la expresión if para determinar el valor de reemplazo
Puede especificar la expresión if en Expression2 de la instrucción XML DML replace value of, tal como se muestra en el ejemplo siguiente. Expression1 identifica que se debe actualizar el atributo LaborHours del primer centro de trabajo. Expression2 utiliza una expresión if para determinar el nuevo valor del atributo 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. Actualizar XML almacenado en una columna XML sin tipo
En el ejemplo siguiente se actualiza XML almacenado en una columna:
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. Actualizar XML almacenado en una columna XML con tipo
En este ejemplo se reemplazan valores de un documento de instrucciones de fabricación almacenado en una columna XML con tipo.
En el ejemplo, se crea en primer lugar una tabla (T) con una columna XML con tipo en la base de datos AdventureWorks2008R2. A continuación, se copia en la tabla T una instancia XML con instrucciones de fabricación procedentes de la columna Instructions de la tabla ProductModel. Después se aplican las inserciones a XML en la tabla T.
use AdventureWorks2008R2;
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="https://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="https://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="https://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;
Tenga en cuenta la utilización de cast al reemplazar el valor LotSize. Esto es necesario cuando el valor debe ser de un tipo específico. En este ejemplo, si el valor fuera 500, la conversión explícita no sería necesaria.