xml sql en español
TRANSCRIPT
-
7/31/2019 xml sql en espaol
1/24
Transacciones en Transact SQL
Concepto de transaccion
Una transaccin es un conjunto de operaciones Transact SQL que se ejecutan como un nico
bloque, es decir, si falla una operacin Transact SQL fallan todas. Si una transaccin tiene xito,todas las modificaciones de los datos realizadas durante la transaccin se confirman y se conviertenen una parte permanente de la base de datos. Si una transaccin encuentra errores y debecancelarse o revertirse, se borran todas las modificaciones de los datos.
El ejemplo clsico de transaccin es una transferencia bancaria, en la que quitamos saldo a unacuenta y lo aadimos en otra. Si no somo capaces de abonar el dinero en la cuenta de destino, nodebemos quitarlo de la cuenta de origen.
SQL Server funciona por defecto con Transacciones de confirmacin automtica, es decir,cada instruccin individual es una transaccin y se confirma automticamente.
Sobre el ejemplo anterior de la transferencia bancaria, un script debera realizar algo parecido alos siguiente:
DECLARE @importe DECIMAL(18,2),
@CuentaOrigenVARCHAR(12),
@CuentaDestinoVARCHAR(12)
/* Asignamos el importe de la transferencia
* y las cuentas de origen y destino
*/
SET @importe = 50
SET @CuentaOrigen ='200700000001'
SET @CuentaDestino ='200700000002'
/* Descontamos el importe de la cuenta origen */
UPDATE CUENTAS
SET SALDO = SALDO - @importe
WHERE NUMCUENTA = @CuentaOrigen
-
7/31/2019 xml sql en espaol
2/24
/* Registramos el movimiento */
INSERTINTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR, IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO + @importe, SALDO, @importe,getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaOrigen
/* Incrementamos el importe de la cuenta destino */
UPDATE CUENTAS
SET SALDO = SALDO + @importe
WHERE NUMCUENTA = @CuentaDestino
/* Registramos el movimiento */
INSERTINTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR, IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO - @importe, SALDO, @importe,getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaDestino
Esta forma de actuar seria erronea, ya que cada instruccin se ejecutaria y confirmara de formaindependiente, por lo que un error dejara los datos erroneos en la base de datos ( y ese es el peor
error que nos podemos encontrar! )
Transacciones implicitas y explicitas
Para agrupar varias sentencias Transact SQL en una nica transaccin, disponemos de lossiguientes mtodos:
-
7/31/2019 xml sql en espaol
3/24
Transacciones explcitasCada transaccin se inicia explcitamente con la instruccin BEGIN TRANSACTION y se terminaexplcitamente con una instruccin COMMIT o ROLLBACK.
Transacciones implcitasSe inicia automtivamente una nueva transaccin cuando se ejecuta una instruccin que realizamodificaciones en los datos, pero cada transaccin se completa explcitamente con una
instruccin COMMIT o ROLLBACK.
Para activar-desactivar el modo de transacciones implicitas debemos ejecutar la siguienteinstruccin.
--Activamos el modo de transacciones implicitas
SETIMPLICIT_TRANSACTIONSON
--Desactivamos el modo de transacciones implicitas
SETIMPLICIT_TRANSACTIONSOFF
Cuando la opcinANSI_DEFAULTS est establecidaen ON, IMPLICIT_TRANSACTIONS tambin se establece en ON.
El siguiente ejemplo muestra el script anterior haciendo uso de transacciones explicitas.
DECLARE @importe DECIMAL(18,2),
@CuentaOrigenVARCHAR(12),
@CuentaDestinoVARCHAR(12)
/* Asignamos el importe de la transferencia
* y las cuentas de origen y destino
*/
SET @importe = 50
SET @CuentaOrigen ='200700000002'
SET @CuentaDestino ='200700000001'
-
7/31/2019 xml sql en espaol
4/24
BEGINTRANSACTION-- O solo BEGIN TRAN
BEGINTRY
/* Descontamos el importe de la cuenta origen */
UPDATE CUENTAS
SET SALDO = SALDO - @importe
WHERE NUMCUENTA = @CuentaOrigen
/* Registramos el movimiento */
INSERTINTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR,IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO + @importe, SALDO, @importe,getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaOrigen
/* Incrementamos el importe de la cuenta destino */
UPDATE CUENTAS
SET SALDO = SALDO + @importe
WHERE NUMCUENTA = @CuentaDestino
/* Registramos el movimiento */
INSERTINTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR,
-
7/31/2019 xml sql en espaol
5/24
IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO - @importe, SALDO, @importe,getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaDestino
/* Confirmamos la transaccion*/
COMMITTRANSACTION-- O solo COMMIT
ENDTRY
BEGINCATCH
/* Hay un error, deshacemos los cambios*/
ROLLBACKTRANSACTION-- O solo ROLLBACK
PRINT'Se ha producido un error!'
ENDCATCH
El siguiente ejemplo muestra el mismo script con transacciones implicitas.
SETIMPLICIT_TRANSACTIONSON
DECLARE @importe DECIMAL(18,2),
@CuentaOrigenVARCHAR(12),
@CuentaDestinoVARCHAR(12)
-
7/31/2019 xml sql en espaol
6/24
/* Asignamos el importe de la transferencia
* y las cuentas de origen y destino
*/
SET @importe = 50
SET @CuentaOrigen ='200700000002'
SET @CuentaDestino ='200700000001'
BEGINTRY
/* Descontamos el importe de la cuenta origen */
UPDATE CUENTAS
SET SALDO = SALDO - @importe
WHERE NUMCUENTA = @CuentaOrigen
/* Registramos el movimiento */
INSERTINTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR,IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO + @importe, SALDO, @importe,getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaOrigen
/* Incrementamos el importe de la cuenta destino */
-
7/31/2019 xml sql en espaol
7/24
UPDATE CUENTAS
SET SALDO = SALDO + @importe
WHERE NUMCUENTA = @CuentaDestino
/* Registramos el movimiento */
INSERTINTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR,IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO - @importe, SALDO, @importe,getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaDestino
/* Confirmamos la transaccion*/
COMMITTRANSACTION-- O solo COMMIT
ENDTRY
BEGINCATCH
/* Hay un error, deshacemos los cambios*/
ROLLBACKTRANSACTION-- O solo ROLLBACK
PRINT'Se ha producido un error!'
ENDCATCH
La transaccin sigue activa hasta que emita una instruccin COMMIT o ROLLBACK. Una vezque la primera transaccin se ha confirmado o revertido, se inicia automticamente una nuevatransaccin la siguiente vez que la conexin ejecuta una instruccion para modificar datos.
-
7/31/2019 xml sql en espaol
8/24
La conexin contina generando transacciones implcitas hasta que se desactiva el modo detransacciones implcitas.
Podemos verificar el nmero de transacciones activas a travs de @@TRANCOUNT.
SETIMPLICIT_TRANSACTIONSON
BEGINTRY
UPDATE CUENTAS SET FXALTA = FXALTA - 1
PRINT@@TRANCOUNT
COMMIT
ENDTRY
BEGINCATCH
ROLLBACK
PRINT'Error'
ENDCATCH
Otro punto a tener en cuenta cuando trabajamos con transacciones son los bloqueos y el nivelde aislamiento.Podemos aprender ms sobre bloqueos y nivel de aislamiento en este articulo .
Transacciones anidadas.
Podemos anidar varias transacciones. Cuando anidamos varias transacciones la instruccinCOMMIT afectar a la ltima transaccin abierta, pero ROLLBACK afectar a todas las transaccionesabiertas.
Un hecho a tener en cuenta, es que, si hacemos ROLLBACK de la transaccin superior sedesharan tambin los cambios de todas las transacciones internas, aunque hayamos realizadoCOMMIT de ellas.
BEGINTRAN
UPDATE EMPLEADOS
SET NOMBRE ='Devjoker'
http://www.devjoker.com/contenidos/Articulos/210/Bloqueos-y-nivel-de-aislamiento-en-SQL-Server-2005.aspxhttp://www.devjoker.com/contenidos/Articulos/210/Bloqueos-y-nivel-de-aislamiento-en-SQL-Server-2005.aspxhttp://www.devjoker.com/contenidos/Articulos/210/Bloqueos-y-nivel-de-aislamiento-en-SQL-Server-2005.aspxhttp://www.devjoker.com/contenidos/Articulos/210/Bloqueos-y-nivel-de-aislamiento-en-SQL-Server-2005.aspx -
7/31/2019 xml sql en espaol
9/24
WHERE ID=101
BEGINTRAN
UPDATE EMPLEADOS
SET APELLIDO1 ='Devjoker.COM'
WHERE ID=101
-- Este COMMIT solo afecta a la segunda transaccion.
COMMIT
-- Este ROLLBACK afecta a las dos transacciones.
ROLLBACK
Una consideracin a tener en cuanta cuando trabajamos con transacciones anidadas es laposibilidad de utilizar puntos de guardado o SAVEPOINTs.
Puntos de recuperacion (SavePoint).
Los puntos de recuperacin (SavePoints) permiten manejar las transacciones por pasos,pudiendo hacer rollbacks hasta un punto marcado por el savepoint y no por toda la transaccin.
El siguiente ejemplo muestra como trabajar con puntos de recuperacin.
BEGINTRAN
UPDATE EMPLEADOS
-
7/31/2019 xml sql en espaol
10/24
SET NOMBRE ='Devjoker'
WHERE ID=101
UPDATE EMPLEADOS
SET APELLIDO1 ='Devjoker.COM'
WHERE ID=101
SAVETRANSACTION P1 -- Guardamos la transaccion (Savepoint)
UPDATE EMPLEADOS
SET APELLIDO1 ='Otra cosa!'
WHERE ID=101
-- Este ROLLBACK afecta solo a las instrucciones
-- posteriores al savepoint P1.
ROLLBACKTRANSACTION P1
-- Confirmamos la transaccion
COMMIT
Using OPENXMLSQL Server 2000
11 out of 21 rated this helpful -Rate this topic
The examples in this topic show how OPENXML is used in creating a rowset view of an XML
document. For information about the syntax of OPENXML, seeOPENXML. The examples show all
http://msdn.microsoft.com/en-us/library/aa226522(v=sql.80).aspx#feedbackhttp://msdn.microsoft.com/en-us/library/aa226522(v=sql.80).aspx#feedbackhttp://msdn.microsoft.com/en-us/library/aa226522(v=sql.80).aspx#feedbackhttp://msdn.microsoft.com/en-us/library/aa276847(v=sql.80).aspxhttp://msdn.microsoft.com/en-us/library/aa276847(v=sql.80).aspxhttp://msdn.microsoft.com/en-us/library/aa276847(v=sql.80).aspxhttp://msdn.microsoft.com/en-us/library/aa276847(v=sql.80).aspxhttp://msdn.microsoft.com/en-us/library/aa226522(v=sql.80).aspx#feedback -
7/31/2019 xml sql en espaol
11/24
aspects of OPENXML except specifying metaproperties in OPENXML. For more information about
specifying metaproperties in OPENXML, seeSpecifying Metaproperties in OPENXML.
Examples
In retrieving the data, rowpattern is used to identify the nodes in the XML document that determinethe rows. rowpattern is expressed in the XPath pattern language used in the MSXML XPath
implementation. For example, if the pattern ends in an element or an attribute, a row is created for
each element or attribute node selected by rowpattern.
The flags value provides default mapping. In the SchemaDeclaration, if no ColPattern is specified,
the mapping specified in flags is assumed. The flags value is ignored ifColPattern is specified
in SchemaDeclaration. The specified ColPattern determines the mapping (attribute-
centric or element-centric) and also the behavior in dealing with overflow and unconsumed data.
A. Execute a simple SELECT statement with OPENXML
The XML document in this example consists of the , , and
elements. The OPENXML statement retrieves customer information in a two-column rowset
(CustomerID and ContactName) from the XML document.
First, the sp_xml_preparedocument stored procedure is called to obtain a document handle. This
document handle is passed to OPENXML.
In the OPENXML statement:
rowpattern (/ROOT/Customer) identifies the nodes to process. The flags parameter value is set to 1 indicating attribute-centric mapping. As a result, the
XML attributes map to the columns in the rowset defined inSchemaDeclaration.
In SchemaDeclaration (in the WITH clause), the specified ColName values match thecorresponding XML attribute names. Therefore, the ColPattern parameter is not specified
in SchemaDeclaration.
And then, the SELECT statement retrieves all the columns in the rowset provided by OPENXML.
DECLARE @idoc intDECLARE @doc varchar(1000)SET @doc ='
http://msdn.microsoft.com/en-us/library/aa226531(v=sql.80).aspxhttp://msdn.microsoft.com/en-us/library/aa226531(v=sql.80).aspxhttp://msdn.microsoft.com/en-us/library/aa226531(v=sql.80).aspxhttp://msdn.microsoft.com/en-us/library/aa226531(v=sql.80).aspx -
7/31/2019 xml sql en espaol
12/24
'-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc-- Execute a SELECT statement using OPENXML rowset provider.SELECT *FROM OPENXML (@idoc, '/ROOT/Customer',1)
WITH (CustomerID varchar(10),ContactName varchar(20))
EXEC sp_xml_removedocument @idoc
This is the result:
CustomerID ContactName---------- --------------------VINET Paul HenriotLILAS Carlos Gonzlez
If the same SELECT statement is executed with flags set to 2, indicating element-centric mapping,
because elements do not have any subelements, the values
ofCustomerID and ContactName for both the customers are returned as NULL.
If in the XML document, the and are subelements, the element-
centric mapping retrieves the values.
DECLARE @idoc intDECLARE @doc varchar(1000)
SET @doc ='
VINETPaul Henriot
LILASCarlos Gonzlez
'-- Create an internal representation of the XML document.EXEC sp_xml_preparedocument @idoc OUTPUT, @doc-- Execute a SELECT statement using OPENXML rowset provider.SELECT *
-
7/31/2019 xml sql en espaol
13/24
FROM OPENXML (@idoc, '/ROOT/Customer',2)WITH (CustomerID varchar(10),
ContactName varchar(20))EXEC sp_xml_removedocument @idoc
This is the result:
CustomerID ContactName---------- --------------------VINET Paul HenriotLILAS Carlos Gonzlez
B. SpecifyColPattern for mapping between rowset columns and the XML attributes/elements
This example shows how the XPath pattern is specified in the optional ColPattern parameter to
provide mapping between rowset columns and the XML attributes (and elements).
The XML document in this example consists of the , , and
elements. The OPENXML statement retrieves customer and order information as a rowset(CustomerID, OrderDate, ProdID, and Qty) from the XML document.
First, the sp_xml_preparedocument stored procedure is called to obtain a document handle. This
document handle is passed to OPENXML.
In the OPENXML statement:
rowpattern (/ROOT/Customer/Order/OrderDetail) identifies the nodes toprocess.
For illustration purposes, the flags parameter value is set to 2 indicating element-centric mapping. However, the mapping specified in ColPattern overwrites this mapping
(the XPath pattern specified in ColPattern maps the columns in the rowset to attributes thus
resulting in an attribute-centric mapping).
In SchemaDeclaration (in the WITH clause), ColPattern is also specified with
the ColName and ColType parameters. The optional ColPattern is the XPath pattern specified to
indicate:
The OrderID, CustomerID, and OrderDate columns in the rowset map to the attributes ofthe parent of the nodes identified by rowpattern. rowpatternidentifies the
nodes. Therefore, the CustomerID and OrderDate columns map
to CustomerID and OrderDate attributes of the element.
The ProdID and Qty columns in the rowset map to the ProductID and Quantity attributesof the nodes identified in rowpattern.
And then the SELECT statement retrieves all the columns in the rowset provided by OPENXML.
DECLARE @idoc int
-
7/31/2019 xml sql en espaol
14/24
DECLARE @doc varchar(1000)SET @doc ='
'-- Create an internal representation of the XML document.EXEC sp_xml_preparedocument @idoc OUTPUT, @doc-- Execute a SELECT stmt using OPENXML rowset provider.
SELECT *FROM OPENXML (@idoc, '/ROOT/Customer/Order/OrderDetail',2)
WITH (OrderID int '../@OrderID',CustomerID varchar(10) '../@CustomerID',OrderDate datetime '../@OrderDate',ProdID int '@ProductID',Qty int '@Quantity')
This is the result:
OrderID CustomerID OrderDate ProdID Qty-------------------------------------------------------------10248 VINET 1996-07-04 00:00:00.000 11 12
10248 VINET 1996-07-04 00:00:00.000 42 1010283 LILAS 1996-08-16 00:00:00.000 72 3
The XPath pattern specified as ColPattern can also be specified to map the XML elements to the
rowset columns (resulting in element-centric mapping). In the following example, the XML
document and are subelements of element.
Because ColPattern overwrites the mapping specified in flags parameter, the flags parameter is not
specified in OPENXML.
DECLARE @idoc intDECLARE @doc varchar(1000)SET @doc ='
10248VINET1996-07-04T00:00:00
-
7/31/2019 xml sql en espaol
15/24
10283LILAS1996-08-16T00:00:00
'-- Create an internal representation of the XML document.EXEC sp_xml_preparedocument @idoc OUTPUT, @doc-- Execute a SELECT stmt using OPENXML rowset provider.SELECT *FROM OPENXML (@idoc, '/ROOT/Customer/Order/OrderDetail')
WITH (CustomerID varchar(10) '../CustomerID',OrderDate datetime '../OrderDate',ProdID int '@ProductID',Qty int '@Quantity')
EXEC sp_xml_removedocument @idoc
C. Combining attribute-centric and element-centric mapping
In this example, the flags parameter is set to 3, indicating that both attribute-centric and element-
centric mapping is to be applied. In this case, the attribute-centric mapping is applied first, and
then element-centric mapping is applied for all the columns not yet dealt with.
DECLARE @idoc intDECLARE @doc varchar(1000)SET @doc ='
Paul Henriot
Carlos Gonzlez
'
-- Create an internal representation of the XML document.EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement using OPENXML rowset provider.SELECT *FROM OPENXML (@idoc, '/ROOT/Customer',3)
WITH (CustomerID varchar(10),ContactName varchar(20))
-
7/31/2019 xml sql en espaol
16/24
EXEC sp_xml_removedocument @idoc
This is the result
CustomerID ContactName---------- --------------------
VINET Paul HenriotLILAS Carlos Gonzlez
The attribute-centric mapping is applied for CustomerID. There is no ContactName attribute in
the element; therefore, element-centric mapping is applied.
D. Specify text() XPath function as ColPattern
The XML document in this example consists of the and elements. The
OPENXML statement retrieves a rowset consisting of the oid attribute from the element,
the ID of the parent of the node (identified by rowpattern), and the leaf-value string of the element
content.
First, the sp_xml_preparedocument stored procedure is called to obtain a document handle. This
document handle is passed to OPENXML.
In the OPENXML statement:
rowpattern (/root/Customer/Order) identifies the nodes to process. The flags parameter value is set to 1, indicating attribute-centric mapping. As a result, the
XML attributes map to the rowset columns defined inSchemaDeclaration.
In SchemaDeclaration (in the WITH clause), the rowset column names, oid and amount,match the corresponding XML attribute names. Therefore, theColPattern parameter is not
specified. For the comment column in the rowset, the XPath function (text()) is specified
as ColPattern. This overwrites theattribute-centric mapping specified in flags, and the
column contains the leaf-value string of the element content.
And then, the SELECT statement retrieves all the columns in the rowset provided by OPENXML.
DECLARE @idoc intDECLARE @doc varchar(1000)--sample XML documentSET @doc ='
Customer was very
satisfied
-
7/31/2019 xml sql en espaol
17/24
ImportantHappy Customer.
'
-- Create an internal representation of the XML document.EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement using OPENXML rowset provider.SELECT *FROM OPENXML (@idoc, '/root/Customer/Order', 1)
WITH (oid char(5),amount float,comment ntext 'text()')
EXEC sp_xml_removedocument @idoc
This is the result:
oid amount comment----- ----------- -----------------------------O1 3.5 NULLO2 13.4 Customer was very satisfiedO3 100.0 Happy Customer.O4 10000.0 NULL
E. SpecifyTableName in the WITH clause
This example specifies TableName in the WITH clause instead ofSchemaDeclaration in the WITH
clause. This is useful if you have a table with the structure you want and no column patterns
(ColPattern parameter) are required.
The XML document in this example consists of the and elements. The
OPENXML statement retrieves order information in a three-column rowset (oid, date, and amount)
from the XML document.
First, the sp_xml_preparedocument stored procedure is called to obtain a document handle. This
document handle is passed to OPENXML.
In the OPENXML statement:
rowpattern (/root/Customer/Order) identifies the nodes to process. There is no SchemaDeclaration in the WITH clause. Instead, a table name is specified.
Therefore, the table schema is used as the rowset schema.
The flags parameter value is set to 1, indicating attribute-centric mapping. Therefore,attributes of the elements (identified by rowpattern) map to the rowset columns with the
same name.
And then the SELECT statement retrieves all the columns in the rowset provided by OPENXML.
-
7/31/2019 xml sql en espaol
18/24
-- Create a test table. This table schema is used by OPENXML as the-- rowset schema.CREATE TABLE T1(oid char(5), date datetime, amount float)DECLARE @idoc intDECLARE @doc varchar(1000)-- Sample XML documentSET @doc ='
Customer was very
satisfied
Important
'--Create an internal representation of the XML document.EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement using OPENXML rowset provider.SELECT *FROM OPENXML (@idoc, '/root/Customer/Order', 1)
WITH T1EXEC sp_xml_removedocument @idoc
This is the result:
oid date amount----- --------------------------- ----------O1 1996-01-20 00:00:00.000 3.5O2 1997-04-30 00:00:00.000 13.4O3 1999-07-14 00:00:00.000 100.0O4 1996-01-20 00:00:00.000 10000.0
F. Obtain the result in an edge table format
In this example, the WITH clause is not specified in the OPENXML statement. As a result, the rowset
generated by OPENXML has an edge table format. The SELECT statement returns all the columns in
the edge table.
The sample XML document in the example consists of the , , and
elements.
First, the sp_xml_preparedocument stored procedure is called to obtain a document handle. This
document handle is passed to OPENXML.
In the OPENXML statement:
-
7/31/2019 xml sql en espaol
19/24
rowpattern (/ROOT/Customer) identifies the nodes to process. The WITH clause is not provided; therefore, OPENXML returns the rowset in an edge table
format.
And then the SELECT statement retrieves all the columns in the edge table.
DECLARE @idoc intDECLARE @doc varchar(1000)SET @doc ='
'--Create an internal representation of the XML document.EXEC sp_xml_preparedocument @idoc OUTPUT, @doc-- Execute a SELECT statement using OPENXML rowset provider.SELECT *FROM OPENXML (@idoc, '/ROOT/Customer')EXEC sp_xml_removedocument @idoc
The result is returned as an edge table. You can write queries against the edge table to obtaininformation:
The following query returns the number ofCustomer nodes in the document. Because theWITH clause is not specified, OPENXML returns an edge table. The SELECT statement
queries the edge table.
SELECT count(*) FROM OPENXML(@idoc, '/') WHERE localname = 'Customer' This query returns local names of XML nodes of element type. SELECT distinct localname FROM OPENXML(@idoc, '/') WHERE nodetype = 1 ORDER BY localname
G. Specifyrowpattern ending with an attribute
The XML document in this example consists of the , , and
elements. The OPENXML statement retrieves order details information in a three-column rowset
(ProductID, Quantity, and OrderID) from the XML document.
-
7/31/2019 xml sql en espaol
20/24
First, the sp_xml_preparedocument is called to obtain a document handle. This document handle
is passed to OPENXML.
In the OPENXML statement:
rowpattern (/ROOT/Customer/Order/OrderDetail/@ProductID) ends with an XML attribute(ProductID). In the resulting rowset, a row is created for each attribute node selected in the
XML document.
In this example, the flags parameter is not specified. Instead, the mappings are specified bythe ColPattern parameter.
In SchemaDeclaration (in the WITH clause), ColPattern is also specified with
the ColName and ColType parameters. The optional ColPattern is the XPath pattern specified to
indicate:
The XPath pattern (.) specified as ColPattern for the ProdID column in the rowset identifiesthe context node (current node). As per the rowpattern specified, it isthe ProductID attribute of the element.
The ColPattern, ../@Quantity, specified for the Qty column in the rowset identifiesthe Quantity attribute of the parent () node of the context node
().
Similarly, the ColPattern, ../../@OrderID, specified for the OID column in the rowsetidentifies the OrderID attribute of the parent () of the parent () node
of the context node ().
And then, the SELECT statement retrieves all the columns in the rowset provided by OPENXML.
DECLARE @idoc intDECLARE @doc varchar(1000)--Sample XML documentSET @doc ='
'-- Create an internal representation of the XML document.EXEC sp_xml_preparedocument @idoc OUTPUT, @doc-- Execute a SELECT stmt using OPENXML rowset provider.
-
7/31/2019 xml sql en espaol
21/24
SELECT *FROM OPENXML (@idoc, '/ROOT/Customer/Order/OrderDetail/@ProductID')
WITH ( ProdID int '.',Qty int '../@Quantity',OID int '../../@OrderID')
EXEC sp_xml_removedocument @idoc
This is the result:
ProdID Qty OID----------- ----------- -------11 12 1024842 10 1024872 3 10283
H. Specify an XML document with multiple text nodes
If you have multiple text nodes in an XML document, a SELECT statement with a ColPattern (text())
returns only the first text node instead of all. For example:
DECLARE @h intEXEC sp_xml_preparedocument @h OUTPUT,
N'TaU
',''
SELECT * FROM openxml(@h, '/root/b:Elem')WITH (Col1 varchar(20) 'text()')
The SELECT statement returns T as the result (and not TaU)
I. Retrieve individual values from multivalued attributes
An XML document can have attributes that are multivalued. For example the IDREFS attribute can
be multivalued. In an XML document, the multivalued attribute values are specified as a string with
the values separated by a space. In the following XML document, the attends attribute of the
element and theattendedBy attribute of are multivalued. Retrieving individual
values from a multivalued XML attribute and storing each value in a separate row in the database
requires additional work. This example shows the process.
This sample XML document consists of the following elements:
Consists ofid (student ID), name, and attends attributes. The attends attribute is a
multivalued attribute.
-
7/31/2019 xml sql en espaol
22/24
Consists ofid (class ID), name, and attendedBy attributes. The attendedBy attribute is a
multivalued attribute.
This attends attribute in and the attendedBy attribute in represent
a m:n relationship between Student and Class tables. A student can take many classes and a class
can have many students.
Assume you want to shred this document and save it in the database as follows:
Save the data in the Students table. Save the data in the Courses table. Save he m:n relationship data (between Student and Class) in the CourseAttendence table.
Additional work is required to extract the values. To retrieve this information and store it in
the table, use these stored procedures: Insert_Idrefs_Values
Inserts the values of course ID and student ID in the CourseAttendence table.
Extract_idrefs_valuesExtracts the individual student IDs from each element. An edge table is
used to retrieve these values.
Here are the steps:
1. Create the following tables:2. DROP TABLE CourseAttendance3. DROP TABLE Students4. DROP TABLE Courses5. GO6. CREATE TABLE Students(7. id varchar(5) primary key,8. name varchar(30)9. )10. GO11. CREATE TABLE Courses(12. id varchar(5) primary key,13. name varchar(30),14. taughtBy varchar(5)15. )16. GO17. CREATE TABLE CourseAttendance(18. id varchar(5) references Courses(id),19. attendedBy varchar(5) references Students(id),20. constraint CourseAttendance_PK primary key (id,
attendedBy)21. )
-
7/31/2019 xml sql en espaol
23/24
22. go23. Create these stored procedures:24. DROP PROCEDURE f_idrefs25. GO26. CREATE PROCEDURE f_idrefs27. @t varchar(500),28. @idtab varchar(50),29. @id varchar(5)30. AS31. DECLARE @sp int32. DECLARE @att varchar(5)33. SET @sp = 034. WHILE (LEN(@t) > 0)35. BEGIN36. SET @sp = CHARINDEX(' ', @t+ ' ')37. SET @att = LEFT(@t, @sp-1)38. EXEC('INSERT INTO '+@idtab+' VALUES ('''+@id+''',
'''+@att+''')')39. SET @t = SUBSTRING(@t+ ' ', @sp+1, LEN(@t)+1-@sp)40. END41. Go42.43. DROP PROCEDURE fill_idrefs44. GO45. CREATE PROCEDURE fill_idrefs46. @xmldoc int,47. @xpath varchar(100),48. @from varchar(50),49. @to varchar(50),50. @idtable varchar(100)51. AS52. DECLARE @t varchar(500)53. DECLARE @id varchar(5)54.55. /* Temporary Edge table */56. SELECT *57. INTO #TempEdge58. FROM OPENXML(@xmldoc, @xpath)59.60. DECLARE fillidrefs_cursor CURSOR FOR61. SELECT CAST(iv.text AS nvarchar(200)) AS id,62. CAST(av.text AS nvarchar(4000)) AS refs63. FROM #TempEdge c, #TempEdge i,64. #TempEdge iv, #TempEdge a, #TempEdge av65. WHERE c.id = i.parentid66. AND UPPER(i.localname) = UPPER(@from)67. AND i.id = iv.parentid68. AND c.id = a.parentid69. AND UPPER(a.localname) = UPPER(@to)70. AND a.id = av.parentid71.72. OPEN fillidrefs_cursor73. FETCH NEXT FROM fillidrefs_cursor INTO @id, @t74. WHILE (@@FETCH_STATUS -1)75. BEGIN76. IF (@@FETCH_STATUS -2)77. BEGIN
-
7/31/2019 xml sql en espaol
24/24
78. execute f_idrefs @t, @idtable, @id79. END80. FETCH NEXT FROM fillidrefs_cursor INTO @id, @t81. END82. CLOSE fillidrefs_cursor83. DEALLOCATE fillidrefs_cursor84. Go85. This is the sample document that is shredded and the data is stored in the preceding tables.86. DECLARE @h int87. EXECUTE sp_xml_preparedocument @h OUTPUT, '88. 89. 90. 91. 92. 93. 94. 95.96. 98. 100. 102. 103. 105. 107.'108.109.INSERT INTO Students SELECT * FROM OPENXML(@h, '//Student') WITH
Students110.111.INSERT INTO Courses SELECT * FROM OPENXML(@h, '//Class') WITH
Courses112./* Using the edge table */113.EXECUTE fill_idrefs @h, '//Class', 'id', 'attendedby',
'CourseAttendance'114.115.SELECT * FROM Students116.SELECT * FROM Courses117.SELECT * FROM CourseAttendance118.
EXECUTE sp_xml_removedocument @h