• No results found

Manipulating XML Data. -- Switching Databases USE XMLPlay;

N/A
N/A
Protected

Academic year: 2022

Share "Manipulating XML Data. -- Switching Databases USE XMLPlay;"

Copied!
37
0
0

Loading.... (view fulltext now)

Full text

(1)

--- -- Total Training for SQL Server 2008

--

-- Lesson 8 - Manipulating XML Data --

-- Paul Nielsen / John Lancashire

--- --- -- Manipulating XML Data

-- Switching Databases USE XMLPlay;

IF OBJECT_ID('Customers','U') IS NOT NULL DROP TABLE Customers CREATE TABLE Customers (

CustomerID INT IDENTITY PRIMARY KEY, CustomerNumber VARCHAR(20),

Name VARCHAR(40), Phone VARCHAR(15), Street VARCHAR(40), City VARCHAR(20), State VARCHAR(10), Zip VARCHAR(10) ) GO

IF OBJECT_ID('Items','U') IS NOT NULL DROP TABLE Items CREATE TABLE Items (

ItemID INT IDENTITY PRIMARY KEY, ItemNumber VARCHAR(20),

ItemDescription VARCHAR(40) ) GO

IF OBJECT_ID('OrderHeader','U') IS NOT NULL DROP TABLE OrderHeader CREATE TABLE OrderHeader (

OrderID INT IDENTITY PRIMARY KEY, OrderNumber VARCHAR(20),

OrderDate DATETIME, CustomerID INT ) GO

(2)

IF OBJECT_ID('OrderDetails','U') IS NOT NULL DROP TABLE OrderDetails CREATE TABLE OrderDetails (

OrderDetailID INT IDENTITY PRIMARY KEY, OrderID INT,

ItemID INT, Quantity INT, Price MONEY )

IF OBJECT_ID('OrderXML','U') IS NOT NULL DROP TABLE OrderXML CREATE TABLE OrderXML (OrderID INT, ItemData XML)

GO

-- Here is some script for Insert query -- Populate Customer Table

INSERT INTO Customers (

CustomerNumber, Name, Phone, Street, City, State, Zip )

SELECT

'J001', 'Jacob Sebastian', '(999) 999-9999', '401, Jacobs Street', 'New York', 'NY', '12345'

-- Populate Items Table

INSERT INTO Items (ItemNumber, ItemDescription) SELECT 'D001','DELL XPS 1130 Laptop'

UNION ALL

SELECT 'Z001','XBOX 360 Console' -- Create order "SO101"

INSERT INTO OrderHeader( OrderNumber, OrderDate, CustomerID ) SELECT 'SO101','2009-01-23',1

-- Add Line Items

INSERT INTO OrderDetails (OrderID, ItemID, Quantity, Price) SELECT 1, 1, 1, 900

UNION ALL

SELECT 1, 2, 1, 200 -- Create order "SO102"

INSERT INTO OrderHeader( OrderNumber, OrderDate, CustomerID ) SELECT 'SO102','2009-01-24',1

-- Add Line Items

INSERT INTO OrderDetails (OrderID, ItemID, Quantity, Price)

(3)

SELECT 2, 1, 1, 900

-- And finally, some XML data

INSERT INTO OrderXML (OrderID, ItemData) SELECT 1, '

<Order OrderID="1">

<Item ItemNumber="D001" Quantity="1" Price="900"/>

<Item ItemNumber="Z001" Quantity="1" Price="200"/>

</Order > '

INSERT INTO OrderXML (OrderID, ItemData) SELECT 2, '

<Order OrderID="2">

<Item ItemNumber="D001" Quantity="1" Price="900"/>

</Order > '

--- -- 2 Creating and using XML columns

DECLARE @t TABLE (OrderID INT,OrderData XML ) INSERT INTO @t(OrderID, OrderData)

SELECT 1,

'<CustomerNumber>1001</CustomerNumber>

<Items>

<Item ItemNumber="1001" Quantity="1" Price="950"/>

<Item ItemNumber="1002" Quantity="1" Price="650"/>

</Items>' SELECT

OrderID,

OrderData.value('CustomerNumber[1]','CHAR(4)') AS CustomerNumber FROM @t

--- -- 3 Some complex Query in XML

-- If the query needs to retrieve more than one element from the XML document stored -- in each row. Such a query needs to generate more than one row against each row -- stored in the base table. The nodes() method of the XML data type can be used to -- obtain an accessor to each element within the XML document.

-- The XML element collection returned by the nodes()method can be joined with the -- base table using the CROSS APPLY operator as shown in the following

(4)

DECLARE @t TABLE (OrderID INT,OrderData XML ) INSERT INTO @t(OrderID, OrderData)

SELECT 1,

'<CustomerNumber>1001</CustomerNumber>

<Items>

<Item ItemNumber="1001" Quantity="1" Price="950"/>

<Item ItemNumber="1002" Quantity="1" Price="650"/>

</Items>' SELECT

OrderID,

o.value('@ItemNumber','CHAR(4)') AS ItemNumber, o.value('@Quantity','INT') AS Quantity,

o.value('@Price','MONEY') AS Price FROM @t

CROSS APPLY OrderData.nodes('/Items/Item') x(o)

--- -- 4 Declaring and Using XML Variables

/*

-- Declare an XML Variable DECLARE @x XML

-- Declare a TYPED XML Variable DECLARE @x XML(CustomerSchema)

-- Declare a TYPED XML DOCUMENT Variable DECLARE @x XML(DOCUMENT CustomerSchema) -- Declare a TYPED XML CONTENT Variable DECLARE @x XML(CONTENT CustomerSchema)

*/

-- Version of the above query that operates on an XML variable DECLARE @x XML

SELECT @x= '

<CustomerNumber>1001</CustomerNumber>

(5)

<Items>

<Item ItemNumber="1001" Quantity="1" Price="950"/>

<Item ItemNumber="1002" Quantity="1" Price="650"/>

</Items>' SELECT

o.value('@ItemNumber','CHAR(4)') AS ItemNumber, o.value('@Quantity','INT') AS Quantity,

o.value('@Price','MONEY') AS Price FROM @x.nodes('/Items/Item') x(o)

--

--- -- 5 Using XML parameters and return values

-- Typed and untyped XML parameters can be passed to a stored procedure -- as INPUT as well as OUTPUT parameters. XML parameters can be used as -- arguments as well as the return value of scalar functions or in result -- columns of table-valued functions. When a function returns an XML data

-- type value, XML data type methods can be directly called on the return value, -- as shown in the following example:

-- Create a function that returns an XML value CREATE FUNCTION GetOrderInfo(

@OrderID INT ) RETURNS XML AS

BEGIN

DECLARE @x XML SELECT @x = (

SELECT OrderID, CustomerID FROM OrderHeader

WHERE OrderID = @OrderID

FOR XML PATH(''),ROOT('OrderInfo')) RETURN @x

END GO

(6)

-- Call the function and invoke the value() method

SELECT dbo.GetOrderInfo(1).value('(OrderInfo/CustomerID)[1]','INT') AS CustomerID

--- -- 6 Loading/querying XML documents from disk files

-- The capability to load XML documents from disk files is one of the very -- interesting XML features available with SQL Server. This is achieved by -- using the BULK row set provider for OPENROWSET. The following example -- shows how to load the content of an XML file into an XML variable:

/*The sample code below assumes that a file named "items.xml"

exists in folder c:\temp with the following content.

<Items>

<Item ItemNumber="1001" Quantity="1" Price="950"/>

<Item ItemNumber="1002" Quantity="1" Price="650" />

</Items>

*/

DECLARE @xml XML SELECT

@xml = CAST(bulkcolumn AS XML)

FROM OPENROWSET(BULK 'c:\temp\items.xml', SINGLE_BLOB) AS x SELECT

x.value('@ItemNumber','CHAR(4)') AS ItemNumber, x.value('@Quantity','INT') AS Quantity,

x.value('@Price','MONEY') AS Price FROM @xml.nodes('/Items/Item') i(x) -- OR

SELECT

x.value('@ItemNumber','CHAR(4)') AS ItemNumber, x.value('@Quantity','INT') AS Quantity,

x.value('@Price','MONEY') AS Price

(7)

FROM (

SELECT CAST(bulkcolumn AS XML) AS data

FROM OPENROWSET(BULK 'c:\temp\items.xml', SINGLE_BLOB) AS x ) a

CROSS APPLY data.nodes('/Items/Item') i(x)

--- -- 7 Limitations of the XML Data Type

DECLARE @EmployeeXML XML, @EmployeeText NVARCHAR(500) SELECT @EmployeeText = '

<EmployeeInfo>

<EmployeeName>Jacob</EmployeeName>

<EmployeeName>Steve</EmployeeName>

<EmployeeName>Rob</EmployeeName>

</EmployeeInfo>'

SELECT DATALENGTH(@EmployeeText) AS StringSize SELECT @EmployeeXML = @EmployeeText

SELECT DATALENGTH(@EmployeeXML) AS XMLSize

--- -- 8 Understanding XML Data Type Methods

/*

XPath

<Items>

<Item ItemNumber="1001" Quantity="1" Price="950"/>

<Item ItemNumber="1002" Quantity="1" Price="650" />

</Items>

*/

/*

value()

*/

DECLARE @x XML

(8)

SELECT @x= '<Order OrderID="1" OrderNumber="S0101" />' SELECT

@x.value('(Order/@OrderID)[1]','INT') AS OrderID,

@x.value('(Order/@OrderNumber)[1]','CHAR(5)') AS OrderNumber /*

nodes()

*/

DECLARE @x XML SELECT @x= '

<Items>

<ItemNumber>1001</ItemNumber>

<ItemNumber>1002</ItemNumber>

</Items>' SELECT

x.value('.','CHAR(4)') AS ItemNumber FROM @x.nodes('/Items/ItemNumber') o(x)

SELECT

OrderID,

x.value('@ItemNumber','CHAR(4)') AS ItemNumber FROM OrderXML

CROSS APPLY ItemData.nodes('/Order/Item') o(x)

/*

exist()

*/

SELECT

OrderID FROM OrderXML

WHERE ItemData.exist('/Order/Item[@ItemNumber = "Z001"]') = 1 --- -- 9 Joining XML Nodes with Relational Tables

(9)

SELECT

oh.OrderID,

c.Name AS Customer,

i.ItemDescription AS Item,

x.value('@Quantity','INT') AS Quantity, x.value('@Price','MONEY') AS Price FROM OrderHeader oh

INNER JOIN OrderXML ox ON

ItemData.value('(Order/@OrderID)[1]','INT') = oh.OrderID CROSS APPLY ItemData.nodes('/Order/Item') o(x)

INNER JOIN Customers c ON c.CustomerID = oh.CustomerID

INNER JOIN Items i ON i.ItemNumber = x.value('@ItemNumber','CHAR(4)') -- OR

SELECT

oh.OrderID,

c.Name AS Customer,

i.ItemDescription AS Item,

x.value('@Quantity','INT') AS Quantity, x.value('@Price','MONEY') AS Price FROM OrderHeader oh

INNER JOIN Customers c ON c.CustomerID = oh.CustomerID CROSS JOIN OrderXML ox

CROSS JOIN Items i

CROSS APPLY ItemData.nodes('

/Order[@OrderID=sql:column("oh.OrderID")]

/Item[@ItemNumber=sql:column("i.ItemNumber")]') o(x) --- -- 10 Using Variables an Filters in XQuery Expressions /* Illegal because it doesn't use a string literal DECLARE @node VARCHAR(100)

SELECT @node = ('/Order/Item') SELECT

(10)

*

FROM OrderXML

CROSS APPLY ItemData.nodes(@node) o(x)

*/

DECLARE @ItemNumber CHAR(4) SELECT @ItemNumber = 'D001' SELECT

x.value('@ItemNumber','CHAR(4)') AS ItemNumber, x.value('@Quantity','INT') AS Quantity,

x.value('@Price','MONEY') AS Price FROM OrderXML

CROSS APPLY ItemData.nodes('

/Order/Item[@ItemNumber=sql:variable("@ItemNumber")]

') o(x) --

DECLARE @Att VARCHAR(50) SELECT @Att = 'ItemNumber' SELECT

x.value('@*[local-name()=sql:variable("@Att")][1]','VARCHAR(50)') AS Value FROM OrderXML

CROSS APPLY ItemData.nodes('/Order/Item') o(x)

--- -- 11 Access the Parent Node

-- This accesses the parent node through the parent node accessor '..' SELECT

x.value('../@OrderID','INT') AS OrderID,

x.value('@ItemNumber','CHAR(4)') AS ItemNumber, x.value('@Quantity','INT') AS Quantity,

x.value('@Price','MONEY') AS Price FROM OrderXML

CROSS APPLY ItemData.nodes('/Order/Item') o(x)

-- This is apparently a more optimised way of doing though.

(11)

-- Using the CROSS APPLY, the query goes forward.

-- The accessor route is slower because it goes backwards.

SELECT

h.value('@OrderID','INT') AS OrderID,

x.value('@ItemNumber','CHAR(4)') AS ItemNumber, x.value('@Quantity','INT') AS Quantity,

x.value('@Price','MONEY') AS Price FROM OrderXML

CROSS APPLY ItemData.nodes('/Order') o(h) CROSS APPLY h.nodes('Item') i(x)

--- -- 12 Generating XML Output Using FOR XML AUTO

SELECT OrderNumber, CustomerID FROM OrderHeader

FOR XML AUTO /*

<OrderHeader OrderNumber="S0101" CustomerID="1" />

<OrderHeader OrderNumber="S0102" CustomerID="1" />

*/

SELECT OrderNumber, CustomerID FROM OrderHeader o

FOR XML AUTO /*

<o OrderHeader OrderNumber="S0101" CustomerID="1" />

<o OrderHeader OrderNumber="S0102" CustomerID="1" />

*/

SELECT OrderNumber, CustomerID FROM OrderHeader

FOR XML AUTO, ROOT('SalesOrder') /*

<SalesOrder>

<OrderHeader OrderNumber="S0101" CustomerID="1" />

<OrderHeader OrderNumber="S0102" CustomerID="1" />

</SalesOrder>

(12)

*/

SELECT

[Order].OrderNumber, [Order].OrderDate,

Customer.CustomerNumber, Customer.Name

FROM OrderHeader [Order]

INNER JOIN Customers Customer ON [Order].CustomerID = Customer.CustomerID FOR XML AUTO

/*

<Order OrderNumber="SO101" OrderDate="2009-01-23T00:00:00">

<Customer CustomerNumber="J001" Name="Jacob Sebastian" />

</Order>

<Order OrderNumber="SO102" OrderDate="2009-01-24T00:00:00">

<Customer CustomerNumber="J001" Name="Jacob Sebastian" />

</Order>

*/

SELECT

[Order].OrderNumber, [Order].OrderDate,

Customer.CustomerNumber, Customer.Name

FROM OrderHeader [Order]

INNER JOIN Customers Customer ON [Order].CustomerID = Customer.CustomerID FOR XML AUTO, ELEMENTS

/*

<Order>

<OrderNumber>SO101</OrderNumber>

<OrderDate>2009-01-23T00:00:00</OrderDate>

<Customer>

<CustomerNumber>J001</CustomerNumber>

<Name>Jacob Sebastian</Name>

</Customer>

</Order>

<Order>

(13)

<OrderNumber>SO102</OrderNumber>

<OrderDate>2009-01-24T00:00:00</OrderDate>

<Customer>

<CustomerNumber>J001</CustomerNumber>

<Name>Jacob Sebastian</Name>

</Customer>

</Order>

*/

--- -- 13 Generating XML Output Using FOR XML RAW

SELECT OrderNumber, CustomerID FROM OrderHeader

FOR XML RAW('Order') /*

<Order OrderNumber="SO101" CustomerID="1" />

<Order OrderNumber="SO102" CustomerID="1" />

*/

SELECT OrderNumber, CustomerNumber FROM OrderHeader o

INNER JOIN Customers c ON o.CustomerID = c.CustomerID FOR XML RAW('Order')

/*

<Order OrderNumber="SO101" CustomerNumber="J001" />

<Order OrderNumber="SO102" CustomerNumber="J001" />

*/

SELECT OrderNumber, CustomerID FROM OrderHeader

FOR XML RAW('Order'), ROOT('Orders') /*

<Orders>

<Order OrderNumber="SO101" CustomerID="1" />

<Order OrderNumber="SO102" CustomerID="1" />

</Orders>

*/

(14)

--- -- 14 Generating XML Output Using FOR XML EXPLICIT

SELECT

1 AS Tag,

NULL AS Parent,

CustomerNumber AS 'Customer!1!CustNo', NULL AS 'LineItems!2!ItemNo',

NULL AS 'LineItems!2!Qty' FROM OrderHeader o

INNER JOIN Customers c ON o.CustomerID = c.CustomerID AND o.OrderID = 1

UNION ALL SELECT

2 AS Tag, 1 AS Parent, NULL,

i.ItemNumber, o.Quantity FROM Items i

INNER JOIN OrderDetails o ON i.ItemID = o.ItemID AND o.OrderID = 1

FOR XML EXPLICIT /*

<Customer CustNo="J001">

<LineItems ItemNo="D001" Qty="1" />

<LineItems ItemNo="Z001" Qty="1" />

</Customer>

OR as follows without FOR XML EXPLICIT

Tag Parent Customer!1!CustNo LineItems!2!ItemNo LineItems!2!Qty --- --- --- --- ---

1 NULL J001 NULL NULL

2 1 NULL D001 1

2 1 NULL Z001 1

(15)

*/

SELECT

1 AS Tag,

NULL AS Parent,

CustomerNumber AS 'Customer!1!CustNo!ELEMENT', NULL AS 'LineItems!2!ItemNo',

NULL AS 'LineItems!2!Qty' FROM OrderHeader o

INNER JOIN Customers c ON o.CustomerID = c.CustomerID AND o.OrderID = 1

UNION ALL SELECT

2 AS Tag, 1 AS Parent, NULL,

i.ItemNumber, o.Quantity FROM Items i

INNER JOIN OrderDetails o ON i.ItemID = o.ItemID AND o.OrderID = 1

FOR XML EXPLICIT /*

<Customer>

<CustNo>J001</CustNo>

<LineItems ItemNo="D001" Qty="1" />

<LineItems ItemNo="Z001" Qty="1" />

</Customer>

*/

SELECT

1 AS Tag,

NULL AS Parent,

CustomerNumber AS 'Order!1!CustNo', OrderNumber AS 'Order!1!OrderNo', NULL AS 'LineItems!2!ItemNo', NULL AS 'LineItems!2!Qty'

(16)

FROM OrderHeader o

INNER JOIN Customers c ON o.CustomerID = c.CustomerID UNION ALL

SELECT

2 AS Tag, 1 AS Parent, NULL,

NULL,

i.ItemNumber, o.Quantity FROM Items i

INNER JOIN OrderDetails o ON i.ItemID = o.ItemID FOR XML EXPLICIT, ROOT('Orders')

/*

<Orders>

<Order CustNo="J001" OrderNo="SO101" />

<Order CustNo="J001" OrderNo="SO102">

<LineItems ItemNo="D001" Qty="1" />

<LineItems ItemNo="Z001" Qty="1" />

<LineItems ItemNo="D001" Qty="1" />

</Order>

</Orders>

Tag Parent Order!1!CustNo Order!1!OrderNo LineItems!2!ItemNo LineItems!2!Qty --- --- --- --- --- ---

1 NULL J001 SO101 NULL NULL

1 NULL J001 SO102 NULL NULL

2 1 NULL NULL D001 1

2 1 NULL NULL Z001 1

2 1 NULL NULL D001 1

*/

SELECT

1 AS Tag,

NULL AS Parent,

CustomerNumber AS 'Order!1!CustNo', OrderNumber AS 'Order!1!OrderNo',

REPLACE(STR(OrderID,4) + STR(0,4),' ','0') AS 'Order!1!Sort!HIDE',

(17)

NULL AS 'LineItems!2!ItemNo', NULL AS 'LineItems!2!Qty' FROM OrderHeader o

INNER JOIN Customers c ON o.CustomerID = c.CustomerID UNION ALL

SELECT

2 AS Tag, 1 AS Parent, NULL,

NULL,

REPLACE(STR(OrderID,4) + STR(OrderDetailID,4),' ','0'), i.ItemNumber,

o.Quantity FROM Items i

INNER JOIN OrderDetails o ON i.ItemID = o.ItemID ORDER BY 'Order!1!Sort!HIDE'

FOR XML EXPLICIT, ROOT('Orders') /*

<Orders>

<Order CustNo="J001" OrderNo="SO101">

<LineItems ItemNo="D001" Qty="1" />

<LineItems ItemNo="Z001" Qty="1" />

</Order>

<Order CustNo="J001" OrderNo="SO102">

<LineItems ItemNo="D001" Qty="1" />

</Order>

</Orders>

Tag Parent CustNo OrderNo Order!1!Sort!HIDE LineItems!2!ItemNo LineItems!2!Qty --- --- --- --- --- --- --- 1 NULL J001 SO101 00010000 NULL NULL

2 1 NULL NULL 00010001 D001 1 2 1 NULL NULL 00010002 Z001 1 1 NULL J001 SO102 00020000 NULL NULL 2 1 NULL NULL 00020003 D001 1

*/

(18)

--- -- 15 Directives

SELECT

1 AS Tag,

NULL AS Parent,

'<Info about="XML"/>' AS 'MyData!1!!ELEMENT' FOR XML EXPLICIT

/*

<MyData>&lt;Info about="XML"/&gt;</MyData>

*/

SELECT

1 AS Tag,

NULL AS Parent,

'<Info about="XML"/>' AS 'MyData!1!!XML' FOR XML EXPLICIT

/*

<MyData>

<Info about="XML" />

</MyData>

*/

SELECT

1 AS Tag,

NULL AS Parent,

'<Info about="XML"/>' AS 'MyData!1!!XMLTEXT' FOR XML EXPLICIT

/*

<MyData about="XML"></MyData>

*/

SELECT

1 AS Tag,

NULL AS Parent,

'<Info about="XML"/>' AS 'MyData!1!!CDATA' FOR XML EXPLICIT

/*

(19)

<MyData><![CDATA[<Info about="XML"/>]]></MyData>

*/

--- -- 16 Using the new simpler XML PATH

SELECT

1 AS Tag,

NULL AS Parent,

OrderNumber AS 'Order!1!OrderNumber', NULL AS 'Customer!2!CustomerNumber', NULL AS 'LineItems!3!',

NULL AS 'LineItems!4!ItemNo', NULL AS 'LineItems!4!Qty' FROM OrderHeader oh

WHERE OrderID = 2 UNION ALL

SELECT

2 AS Tag, 1 AS Parent, NULL,

c.CustomerNumber, NULL,

NULL, NULL

FROM OrderHeader oh

INNER JOIN Customers c ON oh.CustomerID = C.CustomerID AND OrderID = 2

UNION ALL SELECT

3 AS Tag, 1 AS Parent, NULL,

NULL, NULL, NULL, NULL UNION ALL

(20)

SELECT

4 AS Tag, 3 AS Parent, NULL,

NULL, NULL,

i.ItemNumber, od.Quantity FROM OrderDetails od

INNER JOIN Items i ON i.ItemID = od.ItemID AND od.OrderID = 2

FOR XML EXPLICIT, ROOT('Orders') /*

<Orders>

<Order OrderNumber="SO102">

<Customer CustomerNumber="J001" />

<LineItems>

<LineItems ItemNo="D001" Qty="1" />

</LineItems>

</Order>

</Orders>

*/

SELECT

oh.OrderNumber AS '@OrderNumber',

c.CustomerNumber AS 'Customer/@CustomerNumber', i.ItemNumber AS 'LineItems/Item/@ItemNo', od.Quantity AS 'LineItems/Item/@Qty' FROM OrderHeader oh

INNER JOIN Customers c ON oh.CustomerID = c.CustomerID AND OrderID = 2

INNER JOIN OrderDetails od ON od.OrderID = oh.OrderID INNER JOIN Items i ON i.ItemID = od.ItemID

FOR XML PATH('Order'),ROOT('Orders') /*

<Orders>

<Order OrderNumber="SO102">

<Customer CustomerNumber="J001" />

(21)

<LineItems>

<Item ItemNo="D001" Qty="1" />

</LineItems>

</Order>

</Orders>

*/

SELECT

CustomerID AS '@CustomerID', OrderNumber AS 'OrderNumber' FROM OrderHeader

FOR XML PATH('Order'), ROOT('Orders') /*

<Orders>

<Order CustomerID="1">

<OrderNumber>SO101</OrderNumber>

</Order>

<Order CustomerID="1">

<OrderNumber>SO102</OrderNumber>

</Order>

</Orders>

*/

SELECT

CustomerID AS '@CustomerID', OrderNumber AS '*'

FROM OrderHeader

FOR XML PATH('Order'), ROOT('Orders') /*

<Orders>

<Order CustomerID="1">SO101</Order>

<Order CustomerID="1">SO102</Order>

</Orders>

*/

SELECT

ItemNumber AS 'data()' FROM Items

(22)

FOR XML PATH(''), ROOT('Items') /*

<Items>D001 Z001</Items>

*/

SELECT

ItemNumber AS 'text()' FROM Items

FOR XML PATH(''), ROOT('Items') /*

<Items>D001Z001</Items>

*/

SELECT

'Order Number' AS 'comment()', OrderNumber,

'Customer ID' AS 'comment()', CustomerID

FROM OrderHeader WHERE OrderID = 1 FOR XML PATH(''), ROOT('Orders') /*

<Orders>

<!--Order Number-->

<OrderNumber>SO101</OrderNumber>

<!--Customer ID-->

<CustomerID>1</CustomerID>

</Orders>

*/

--- -- 17 The TYPE Directive

SELECT

SalesOrder.OrderNumber, SalesOrder.OrderDate, (SELECT CustomerNumber,

Name

FROM Customers Customer

(23)

FOR XML AUTO, TYPE), (SELECT ItemNumber,

Quantity, Price

FROM (SELECT i.ItemNumber, o.Quantity, o.Price FROM Items i

INNER JOIN OrderDetails o ON i.ItemID = o.ItemID WHERE OrderID = 1

) Item

FOR XML AUTO, ROOT('Items'),TYPE) FROM OrderHeader SalesOrder

WHERE OrderID = 1 FOR XML AUTO /*

<SalesOrder OrderNumber="SO101" OrderDate="2009-01-23T00:00:00">

<Customer CustomerNumber="J001" Name="Jacob Sebastian" />

<Items>

<Item ItemNumber="D001" Quantity="1" Price="900.0000" />

<Item ItemNumber="Z001" Quantity="1" Price="200.0000" />

</Items>

</SalesOrder>

*/

SELECT (SELECT OrderID, CustomerID FROM OrderHeader

FOR XML AUTO, TYPE

).value('(OrderHeader/@OrderID)[1]','INT') AS OrderID

--- -- 18 The XSINIL Directive

SELECT OrderNumber, CustomerID,

NULL AS CustomerPhone FROM OrderHeader [Order]

FOR XML AUTO, ELEMENTS XSINIL

(24)

/*

<Order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<OrderNumber>SO101</OrderNumber>

<CustomerID>1</CustomerID>

<CustomerPhone xsi:nil="true" />

</Order>

<Order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<OrderNumber>SO102</OrderNumber>

<CustomerID>1</CustomerID>

<CustomerPhone xsi:nil="true" />

</Order>

*/

--- -- 19 Generating XML Schema Information

SELECT OrderNumber, CustomerID

FROM OrderHeader [Order]

FOR XML AUTO, XMLDATA /*

<Schema name="Schema1" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft- com:datatypes">

<ElementType name="Order" content="empty" model="closed">

<AttributeType name="OrderNumber" dt:type="string" />

<AttributeType name="CustomerID" dt:type="i4" />

<attribute type="OrderNumber" />

<attribute type="CustomerID" />

</ElementType>

</Schema>

<Order xmlns="x-schema:#Schema1" OrderNumber="SO101" CustomerID="1" />

<Order xmlns="x-schema:#Schema1" OrderNumber="SO102" CustomerID="1" />

*/

SELECT OrderNumber, CustomerID

FROM OrderHeader [Order]

FOR XML AUTO, XMLSCHEMA

(25)

/*

<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:schema="urn:schemas-microsoft- com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">

<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes"

schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />

<xsd:element name="Order">

<xsd:complexType>

<xsd:attribute name="OrderNumber">

<xsd:simpleType>

<xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1033"

sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">

<xsd:maxLength value="20" />

</xsd:restriction>

</xsd:simpleType>

</xsd:attribute>

<xsd:attribute name="CustomerID" type="sqltypes:int" />

</xsd:complexType>

</xsd:element>

</xsd:schema>

<Order xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1" OrderNumber="SO101" CustomerID="1" />

<Order xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1" OrderNumber="SO102" CustomerID="1" />

*/

SELECT OrderNumber, CustomerID

FROM OrderHeader [Order]

FOR XML AUTO, XMLSCHEMA('urn:some-namespace') /*

<xsd:schema targetNamespace="urn:some-namespace" xmlns:schema="urn:some-namespace"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">

<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes"

schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />

<xsd:element name="Order">

<xsd:complexType>

<xsd:attribute name="OrderNumber">

<xsd:simpleType>

(26)

<xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1033"

sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">

<xsd:maxLength value="20" />

</xsd:restriction>

</xsd:simpleType>

</xsd:attribute>

<xsd:attribute name="CustomerID" type="sqltypes:int" />

</xsd:complexType>

</xsd:element>

</xsd:schema>

<Order xmlns="urn:some-namespace" OrderNumber="SO101" CustomerID="1" />

<Order xmlns="urn:some-namespace" OrderNumber="SO102" CustomerID="1" />

*/

--- -- 20 Generating XML Namespaces

;WITH XMLNAMESPACES(

'http://www.sqlserverbible.com/orders' AS ord )

SELECT

CustomerID AS '@CustomerID', OrderNumber AS 'data()' FROM OrderHeader

FOR XML PATH('Order'),ROOT('Orders') /*

<Orders xmlns:ord="http://www.sqlserverbible.com/orders">

<Order CustomerID="1">SO101</Order>

<Order CustomerID="1">SO102</Order>

</Orders>

*/

;WITH XMLNAMESPACES(

DEFAULT 'http://www.sqlserverbible.com/orders' )

SELECT

CustomerID AS '@CustomerID', OrderNumber AS 'data()'

(27)

FROM OrderHeader

FOR XML PATH('Order'),ROOT('Orders') /*

<Orders xmlns="http://www.sqlserverbible.com/orders">

<Order CustomerID="1">SO101</Order>

<Order CustomerID="1">SO102</Order>

</Orders>

*/

;WITH XMLNAMESPACES(

'http://www.sqlserverbible.com/customers' AS cust, 'http://www.sqlserverbible.com/orders' AS ord )

SELECT

OrderNumber AS 'ord:OrderNumber', CustomerID AS 'cust:CustomerID' FROM OrderHeader WHERE OrderID = 1 FOR XML PATH(''),ROOT('Orders') /*

<Orders xmlns:ord="http://www.sqlserverbible.com/orders"

xmlns:cust="http://www.sqlserverbible.com/customers">

<ord:OrderNumber>SO101</ord:OrderNumber>

<cust:CustomerID>1</cust:CustomerID>

</Orders>

*/

--- -- 21 Understanding XQuery and FLWOR Operations

SELECT ItemData.query('/Order/Item') FROM OrderXML

/*

<Item ItemNumber="D001" Quantity="1" Price="900" />

<Item ItemNumber="Z001" Quantity="1" Price="200" />

<Item ItemNumber="D001" Quantity="1" Price="900" />

*/

SELECT ItemData.query('/Order/Item[@ItemNumber="D001"]')

(28)

FROM OrderXML /*

<Item ItemNumber="D001" Quantity="1" Price="900" />

<Item ItemNumber="D001" Quantity="1" Price="900" />

*/

SELECT OrderID,

ItemData.query('

count(/Order/Item)

').value('.','INT') AS LineCount FROM OrderXML

--- -- 22 FLWOR Operation

DECLARE @x XML SELECT @x = ' <Items>

<ItemNumber>1003</ItemNumber>

<ItemNumber>1004</ItemNumber>

</Items>' SELECT

@x.query('

for $item in Items/ItemNumber return $item ')

/*

<ItemNumber>1003</ItemNumber>

<ItemNumber>1004</ItemNumber>

*/

DECLARE @x XML SELECT @x = ' <Items>

<ItemNumber>1003</ItemNumber>

<ItemNumber>1004</ItemNumber>

<ItemNumber>1001</ItemNumber>

<ItemNumber>2007</ItemNumber>

(29)

<ItemNumber>3009</ItemNumber>

<ItemNumber>4005</ItemNumber>

</Items>' SELECT

@x.query('

for $item in Items/ItemNumber where $item[. < "2000"]

order by $item return $item ') /*

<ItemNumber>1001</ItemNumber>

<ItemNumber>1003</ItemNumber>

<ItemNumber>1004</ItemNumber>

*/

DECLARE @x XML SELECT @x = '

<Item ItemNumber="D001" Quantity="1" Price="900" />

<Item ItemNumber="Z001" Quantity="1" Price="200" />' SELECT

@x.query('

for $item in Item return

<ItemNumber>

{data($item/@ItemNumber)}

</ItemNumber> ') /*

<ItemNumber>D001</ItemNumber>

<ItemNumber>Z001</ItemNumber>

*/

--- -- 23 What's New for XQuery in SQL Server 2008

DECLARE @x XML SELECT @x = '

(30)

<Item ItemNumber="D001" Quantity="1" Price="900" />

<Item ItemNumber="Z001" Quantity="1" Price="200" />' SELECT

@x.query('

for $item in Item

let $itm := $item/@ItemNumber

let $tot := $item/@Quantity * $item/@Price return

<Item>

<ItemNumber>{data($itm)}</ItemNumber>

<TotalPrice>{data($itm)}</TotalPrice>

</Item>

') /*

<Item>

<ItemNumber>D001</ItemNumber>

<TotalPrice>D001</TotalPrice>

</Item>

<Item>

<ItemNumber>Z001</ItemNumber>

<TotalPrice>Z001</TotalPrice>

</Item>

*/

--- -- 24 Performing XML Data Modification

-- Insert DECLARE @x XML

SELECT @x = '<SalesOrder OrderNumber="S0101"/>' DECLARE @CustomerID INT

SELECT @CustomerID = 1 SET @x.modify('

insert element CustomerID {sql:variable("@CustomerID")}

as last into (SalesOrder)[1]

')

(31)

SELECT @x /*

<SalesOrder OrderNumber="S0101">

<CustomerID>1</CustomerID>

</SalesOrder>

*/

-- Delete DECLARE @x XML SELECT @x = '

<SalesOrder OrderNumber="S0101">

<CustomerID>1</CustomerID>

</SalesOrder>

'

DECLARE @CustomerID INT SELECT @CustomerID = 2 SET @x.modify('

delete (SalesOrder/CustomerID)[1]

') SELECT @x /*

<SalesOrder OrderNumber="S0101" />

*/

--- -- 25 What's New in XML DML in SQL Server 2008

DECLARE @doc XML, @val XML SELECT @doc = '

<SalesOrder OrderNumber="S0101">

<CustomerID>1</CustomerID>

</SalesOrder>

'

(32)

SELECT @val = '

<Items>

<Item ItemNumber="Z001" Quantity="1" Price="900"/>

</Items>

'

SET @doc.modify('

insert sql:variable("@val") as last into (SalesOrder)[1]

') SELECT @doc /*

<SalesOrder OrderNumber="S0101">

<CustomerID>1</CustomerID>

<Items>

<Item ItemNumber="Z001" Quantity="1" Price="900" />

</Items>

</SalesOrder>

*/

--- -- 26 Handling Namespaces

DECLARE @x XML SELECT @x = '

<SalesOrder xmlns="http://www.sqlserverbible.com/order"

xmlns:cust="http://www.sqlserverbible.com/customer">

<OrderID>1</OrderID>

<cust:CustomerID>10001</cust:CustomerID>

</SalesOrder>

'

;WITH XMLNAMESPACES(

DEFAULT 'http://www.sqlserverbible.com/order',

'http://www.sqlserverbible.com/customer' AS cust )

SELECT

(33)

@x.value('(SalesOrder/OrderID)[1]','INT') AS OrderID,

@x.value('(SalesOrder/cust:CustomerID)[1]','INT') AS CustomerID ---

-- 27 Shredding XML USING OPENXML() DECLARE @hdoc INT

DECLARE @xml VARCHAR(MAX) SET @xml ='

<SalesOrder OrderNumber="S0101">

<Items>

<Item ItemNumber="D001" Quantity="1" Price="900.0000" />

<Item ItemNumber="Z001" Quantity="1" Price="200.0000" />

</Items>

</SalesOrder>

'

-- Step 1: Initialise XML Document Handle EXEC sp_xml_preparedocument @hdoc OUTPUT, @xml -- Step 2: Call OPENXML

SELECT * FROM OPENXML(@hdoc, '/SalesOrder/Items/Item') WITH (

OrderNumber CHAR(5) '../../@OrderNumber', ItemNumber CHAR(4) '@ItemNumber',

Quantity INT '@Quantity', Price MONEY '@Price' )

-- Step 3: Free document handle exec sp_xml_removedocument @hdoc /*

OrderNumber ItemNumber Quantity Price --- --- --- ---

S0101 D001 1 900.00

S0101 Z001 1 200.00

*/

(34)

DECLARE @hdoc INT

DECLARE @xml VARCHAR(MAX) SET @xml ='

<itm:Items xmlns:itm="http://www.sqlserverbible.com/items">

<itm:Item ItemNumber="D001" Quantity="1" Price="900.0000" />

<itm:Item ItemNumber="Z001" Quantity="1" Price="200.0000" />

</itm:Items>

'

-- Step 1: Initialise XML Document Handle EXEC sp_xml_preparedocument

@hdoc OUTPUT, @xml,

'<itm:Items xmlns:itm="http://www.sqlserverbible.com/items"/>' -- Step 2: Call OPENXML

SELECT * FROM OPENXML(@hdoc, 'itm:Items/itm:Item') WITH (

ItemNumber CHAR(4) '@ItemNumber', Quantity INT '@Quantity',

Price MONEY '@Price' )

-- Step 3: Free document handle exec sp_xml_removedocument @hdoc /*

ItemNumber Quantity Price --- --- ---

D001 1 900.00

Z001 1 200.00

*/

--- -- 28 XSD and XML Schema Collections

-- Creating an XML Schema Collection

(35)

CREATE XML SCHEMA COLLECTION CustomerSchema AS '

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="Customer">

<xs:complexType>

<xs:attribute name="CustomerID" use="required">

<xs:simpleType>

<xs:restriction base="xs:integer">

<xs:minInclusive value="1"/>

<xs:maxInclusive value="9999"/>

</xs:restriction>

</xs:simpleType>

</xs:attribute>

<xs:attribute name="CustomerName" use="optional">

<xs:simpleType>

<xs:restriction base="xs:string">

<xs:maxLength value="40"/>

</xs:restriction>

</xs:simpleType>

</xs:attribute>

</xs:complexType>

</xs:element>

</xs:schema>

'

-- Creating Typed XML Columns and Variables -- Create an XML Type Variable

DECLARE @x XML(CustomerSchema)

-- Create a Table with an XML Typed Column CREATE Table TypedXML(

ID INT,

CustomerData XML(CustomerSchema)) -- Alter a Table to Add an XML Typed Column

ALTER TABLE TypedXML ADD Customer2 XML(CustomerSchema) -- Performing Validation

DECLARE @x XML(CustomerSchema)

(36)

SELECT @x = '<Customer CustomerID="19909" CustomerName="Jacob"/>' -- Msg 6926, Level 16, State 1, Line 2

-- XML Validation: Invalid simple type value: '19909'. Location: /*:Customer[1]/@*:CustomerID -- XML Document

DECLARE @x XML(CONTENT CustomerSchema)

SELECT @x = '<Customer CustomerID="1001" CustomerName="Jacob"/>' -- XML Document

DECLARE @x XML(CONTENT CustomerSchema) SELECT @x = '

<Customer CustomerID="1001" CustomerName="Jacob"/>

<Customer CustomerID="1002" CustomerName="Steve"/>

'

-- Adding Schemas to a Schema Collection -- Creating an XML Schema Collection

CREATE XML SCHEMA COLLECTION CustomerOrOrder AS '

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="Customer">

<xs:complexType>

<xs:attribute name="CustomerID"/>

<xs:attribute name="CustomerName"/>

</xs:complexType>

</xs:element>

<xs:element name="Order">

<xs:complexType>

<xs:attribute name="OrderID"/>

<xs:attribute name="OrderNumber"/>

</xs:complexType>

</xs:element>

</xs:schema>

'

-- XML Document

DECLARE @x XML(CustomerOrOrder)

SELECT @x = '<Customer CustomerID="1001" CustomerName="Jacob"/>'

(37)

SELECT @x = '<Order OrderID="121" OrderNumber="10001"/>' SELECT @x = '

<Customer CustomerID="1001" CustomerName="Jacob"/>

<Order OrderID="121" OrderNumber="10001"/>

'

ALTER XML SCHEMA COLLECTION CustomerOrOrder ADD '

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="Item">

<xs:complexType>

<xs:attribute name="ItemID"/>

<xs:attribute name="ItemNumber"/>

</xs:complexType>

</xs:element>

</xs:schema>

'

-- Tidy Up IF EXISTS(

SELECT name FROM sys.xml_schema_collections

WHERE schema_id = schema_id('dbo') AND name = 'CustomerOrOrder' ) DROP XML SCHEMA COLLECTION CustomerOrOrder

IF OBJECT_ID('TypedXML','U') IS NOT NULL DROP TABLE TypedXML GO

IF EXISTS(

SELECT name FROM sys.xml_schema_collections

WHERE schema_id = schema_id('dbo') AND name = 'CustomerSchema' ) DROP XML SCHEMA COLLECTION CustomerSchema

References

Related documents

The FSC logo, the initials ‘FSC’ and the name ‘Forest Stewardship Council’ are registered trademarks, and therefore a trademark symbol must accompany the.. trademarks in

discharged from the trust, or refuses or becomes, in the opinion of a principal civil court of original jurisdiction, unfit or personally incapable to act in the trust, or accepts

The goals for sprint 3 were to design and begin the development of the wizard page of the application, to be used in the processing of cases defined in incoming?.

In the case where the system is cointegrated, the long-run and short run models in equations 11 and 12 respectively are estimated and the error correction term which enters the

When tropical trees do form ECM symbioses, they are more likely to become locally dominant [6] or in some cases regionally dominant (e.g., the Dipterocarpaceae in Southeast Asia).

Ideally, coating of the bare metal surface would lead to a highly insulating surface, a decrease in direct current and deposition of the paint to only cover the bare metal surface

Attributes and relational databases, fact table contains a collection elements of queries of xml schema url to relate to?. Xml schema collection by all start from xsd to

The XML schema collection stores the imported XML schemas and quantity then used to clay the following Validate XML instances Type the XML data domain it is stored in church