1. Trang chủ
  2. » Công Nghệ Thông Tin

Microsoft SQL Server 2008 R2 Unleashed- P191 pptx

10 66 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 290,22 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

You can do this easily if the stored XML is well formed, as in the following example: CREATE TABLE NTextXml NTextXmlColumn ntext NULL GO INSERT NTextXml SELECT ‘ Lot's of Junk!.

Trang 1

But this statement succeeds:

INSERT XmlExample SELECT ‘<root><foo/></root>’

Let’s say you manage the data for a company that has just upgraded from SQL Server 2000

to 2008 You already store all your XML inside ntextcolumns, and it’s time to convert

those columns to xml You can do this easily if the stored XML is well formed, as in the

following example:

CREATE TABLE NTextXml

(

NTextXmlColumn ntext NULL

)

GO

INSERT NTextXml

SELECT

‘<feedback_review>

<parts_order id=”106”>

<customer_comment>Lot&apos;s of Junk!</customer_comment>

</parts_order>

</feedback_review>’

GO

ALTER TABLE NTextXml

ALTER COLUMN NTextXmlColumn xml NULL

Next, you would like to ensure that all your XML validates against a schema To change the

column from typed to untyped XML by associating a schema, you execute the following:

ALTER TABLE NTextXml

ALTER COLUMN NTextXmlColumn xml

(DOCUMENT HumanResources.HRResumeSchemaCollection)

go

XML Validation: Declaration not found for element ‘feedback_review’.

Location: /*:feedback_review[1]

The statement has been terminated.

Notice the error generated The reason is that the tags used are not defined in the

schemas ofHRResumeSchemaCollection, so the XML does not validate, and theALTER

TABLEstatement fails What you really want is for the XML to validate against your own

schema, which is described in the next section

Using XML Schema Collections

In this section, you define a simple XML schema, add it to a new schema collection stored

on the server, and create a table where you can store instances of this schema You also

add a check constraint to ensure that the value of the ProductIdattribute of the XML’s

root node matches the value of the ProductIdcolumn, using the xmldata type value()

method (discussed later in this chapter, in the section, “The Built-in xmlData Type

Trang 2

Methods”) The foreign key constraint you define on ProductIdalso serves to ensure that

bothProductIdvalues reference a primary key value in HumanResources.Product

The real-world concept behind this sample schema is that it defines groups of customer

feedback calls and subsequent corporate responses pertaining to different kinds of orders

Listing 47.14 shows the schema and table definition

LISTING 47.14 An XSD and Table for Modeling and Storing Customer Feedback Reviews

use AdventureWorks2008

go

CREATE XML SCHEMA COLLECTION Sales.FeedbackSchemaCollection AS

‘<?xml version=”1.0”?>

<xsd:schema

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

targetNamespace=”urn:www-samspublishing-com:examples:feedback_review_xsd”

xmlns=”urn:www-samspublishing-com:examples:feedback_review_xsd”

elementFormDefault=”qualified”

attributeFormDefault=”unqualified”>

<xsd:element name=”feedback_review” type=”feedbackReviewType”/>

<xsd:complexType name=”feedbackReviewType”>

<xsd:sequence minOccurs=”1” maxOccurs=”unbounded”>

<xsd:element name=”order” type=”orderType”/>

</xsd:sequence>

<xsd:attribute

name=”product_id”

type=”xsd:integer”

use=”optional”/>

</xsd:complexType>

<xsd:complexType name=”feedbackType” mixed=”true”>

<xsd:attribute name=”id” type=”xsd:integer” use=”required”/>

</xsd:complexType>

<xsd:complexType name=”orderType”>

<xsd:choice minOccurs=”0” maxOccurs=”unbounded”>

<xsd:element name=”customer_comment” type=”feedbackType”/>

<xsd:element name=”company_response” type=”feedbackType”/>

</xsd:choice>

<xsd:attribute name=”id” type=”xsd:integer” use=”required”/>

<xsd:attribute name=”type” use=”required”>

<xsd:simpleType>

<xsd:restriction base=”xsd:string”>

<xsd:enumeration value=”parts”/>

<xsd:enumeration value=”product”/>

<xsd:enumeration value=”service”/>

</xsd:restriction>

</xsd:simpleType>

Trang 3

</xsd:attribute>

</xsd:complexType>

</xsd:schema>’

GO

CREATE FUNCTION Sales.fnCheckProductId

(

@FeedbackReviewXml xml

)

RETURNS int

AS

BEGIN

DECLARE @ProductId int

SELECT @ProductId = @FeedbackReviewXml.value(‘

declare namespace

fr=”urn:www-samspublishing-com:examples:feedback_review_xsd”;

/fr:feedback_review[1]/@product_id’, ‘int’) RETURN @ProductId

END

GO

CREATE TABLE Sales.FeedbackReview

(

FeedbackReviewId int IDENTITY(1, 1) NOT NULL PRIMARY KEY,

ProductId int NULL REFERENCES Production.Product,

FeedbackReviewXml xml (DOCUMENT Sales.FeedbackSchemaCollection) NOT NULL,

CONSTRAINT ProductIdMatches

CHECK (Sales.fnCheckProductId(FeedbackReviewXml) = ProductId)

)

GO

Having created the xmlcolumn, you can now insert valid, well-formed documents into

FeedbackReviewin the following manner:

INSERT Sales.FeedbackReview

SELECT

NULL,

‘<feedback_review

xmlns=”urn:www-samspublishing-com:examples:feedback_review_xsd”>

<order id=”353” type=”service”>

<customer_comment id=”131”>

You guys said you&apos;d be here on Monday.

</customer_comment>

<company_response id=”242”>I said Wednesday!</company_response>

</order>

Trang 4

</feedback_review>’

GO

(1 row(s) affected)

UsingINSERT, you can input XML into xmlcolumns as varchar,xml, or literal string data,

or you can insert the output of a subquery that returns these types

The syntax used to create an XML schema collection is simple and straightforward:

CREATE SCHEMA COLLECTION schema_collection_name AS schema

Theschemaparameter can be either a string (as shown), or a variable that contains the

text of the schema of typevarchar,nvarchar,varbinary,nvarbinary, or xml

Dropping a schema collection is just as easy:

DROP SCHEMA COLLECTION schema_collection_name

If you ever want to select your schema back out again, you simply call the system

func-tionxml_schema_namespace, as in the following example:

SELECT xml_schema_namespace(

‘Sales’,

‘FeedbackSchemaCollection’,

‘urn:www-samspublishing-com:examples:feedback_review_xsd’

)

To add additional schemas to the collection, you use ALTER XML SCHEMA COLLECTION:

ALTER XML SCHEMA COLLECTION

Sales.FeedbackSchemaCollection ADD another schema

To view some of the nodes in your stored XML schemas, you query

sys.xml_schema_collectionand its related catalog views Here’s an example:

use AdventureWorks2008

go

SELECT el.name, el.*, el.must_be_qualified

FROM sys.columns sc

JOIN sys.xml_schema_collections xs

ON sc.xml_collection_id = xs.xml_collection_id

JOIN sys.xml_schema_elements el

ON xs.xml_collection_id = el.xml_collection_id

WHERE sc.name = ‘FeedbackReviewXml’

Given the name of the table’s typed xmlcolumn (FeedbackReviewXml), you can find its

associated schema collection by querying the catalog views as follows:

SELECT

sc.name XmlColumnName,

Trang 5

xs.name CollectionName,

ns.name Namespace

from sys.columns sc

JOIN sys.xml_schema_collections xs

ON sc.xml_collection_id = xs.xml_collection_id

JOIN sys.xml_schema_namespaces ns

ON ns.xml_collection_id = sc.xml_collection_id

WHERE sc.name = ‘FeedbackReviewXml’

go

XmlColumnName CollectionName Namespace

-FeedbackReviewXml FeedbackSchemaCollection

urn:www-samspublishing-com:examples:feedback_review_xsd

You can accomplish the same thing by using the Object Browser in SSMS by viewing the

properties of the xmlcolumn or by right-clicking the Modify menu choice on the table

object, as shown in Figure 47.1

You can control permissions on schema collections by using the standard ALTER,CONTROL,

TAKE OWNERSHIP,REFERENCES,VIEW DEFINITION, and EXECUTEsyntax Here’s an example:

GRANT ALTER ON XML SCHEMA COLLECTION::Sales.FeedbackSchemaCollection

TO some_login

FIGURE 47.1 Viewing the properties of an xml column in SSMS.

Trang 6

There are a few unsupported XML schema features in schema collections Check the Books

Online article titled “Guidelines and Limitations of XML Schema Collections on the

Server” for the most up-to-date information Following are some notable limitations:

The XSD constraints key,keyref, and uniqueare not supported

XSDincludeandredefineare not supported

Lax validation is not supported

You can also manage XML schema collections using SSMS To do so, you open the Object

Browser and expand the main tree to the following node:

ServerName\Databases\AdventureWorks2008\Programmability\Types\XML Schema

Collections Then you right-click a schema collection to drop it or to add new schemas.

You can also easily script schemas out for review whenever needed Figure 47.2 shows the

expanded Object Browser tree

The Built-in xml Data Type Methods

Now that you know how to create and manage typed and untyped xmlcolumns, the next

step is to learn how to query and modify stored XML content Although SQL Server

supports only a subset of the XQuery 1.0 recommendation, you’ll soon see that it’s plenty

to get the job done

FIGURE 47.2 Using the Object Browser to manage XML schema collections

Trang 7

Keep in mind that a mastery of XQuery is not a requirement for selecting out XML data;

you can just specify the name of the xmlcolumn to select all the data back at once

SQL Server provides five built-in methods on the xmldata type: query(),exists(),

value(),nodes(), and modify() These methods are appended to the name of the xml

column in question, using the ColumnName.MethodName([MethodParameters])syntax

These methods work on XML in the following ways:

query()—Evaluates an XQuery expression into a node list, allowing for reshaping of

the selected nodes Results in untyped XML

exists()—Performs a Boolean test to see whether the result of an XQuery

expres-sion is empty (no matching nodes) Returns 1(non-empty), or 0(empty)

value()—Extracts a single (that is, scalar) value from an XML node and casts it to a

SQL Server relational data type (for example, int,varchar)

nodes()—Uses an XQuery expression to decompose the XML input into a rowset;

this is similar to the effect of OPENXML

modify()—Alters the content of an XML document using the insert,replace value

of, and deleteXQuery functions

XQuery is a bit like T-SQL in that it uses similar SELECT-FROM-WHERE-ORDER BYsemantics

to find the required nodes It also bears a resemblance to writing foreachloops with

object iterators in a language such as C# It is unique in that it combines the navigational

power of XPath to locate nodes and (in the same expressions) allows for new XML

genera-tion on the fly, all in one tight syntax package built especially for processing XML

To use XQuery effectively, you need to have at least a rudimentary understanding of

XPath A great starting point is the World Wide Web Consortium’s (W3C’s) site, at www

w3.org/TR/xpath20/ The following subsections assume such basic knowledge

Selecting XML by Using query()

The job of query()is to retrieve XML nodes by using XQuery expressions The result of

query()is an instance of untyped xml It takes a single parameter, a string literal

contain-ing the XQuery code itself

NOTE

Like all the other four xmldata type methods (and unlike most other T-SQL keywords),

query()is case sensitive This is in keeping with the case sensitivity of XML itself

NOTE

The parameter to query()cannot be a variable; it must be a string literal This puts

something of a hold on dynamic XQuery expressions However, declared T-SQL variables

and column values are available for use in XQuery, using the functions

sql:variable()andsql:column()(described later in this chapter)

Trang 8

Each XQuery query is broken into two distinct parts, separated by a semicolon The first

part is known as the prolog This is the place where any namespaces used in the XPath

expressions and selected nodes are declared The second part is known as the body, and

this is the place where XPath and XQuery expressions are evaluated

The following example declares the actnamespace in its query prolog and then selects

anyact:eMailnodes from Person.Person.AdditionalContactInfoin its body:

SELECT

AdditionalContactInfo.query(

declare namespace

act=”http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes”;

//act:eMail

)

FROM Person.Person

WHERE ContactId = 2

go

<act:eMail

xmlns:act=”http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes”>

<act:eMailAddress>Joe@xyz.com</act:eMailAddress>

<act:SpecialInstructions>

Dont send emails for urgent issues Use telephone instead.

</act:SpecialInstructions>

</act:eMail>

Note that as with FOR XML, the result of query()can sometimes be an XML fragment (or

an empty string) You can again use FOR XML RAW, ROOTto guarantee that this won’t

happen Listing 47.15 illustrates this use, as well as the WITH XMLNAMESPACESstatement

LISTING 47.15 UsingWITH XMLNAMESPACES with FOR XML and query()

WITH XMLNAMESPACES

(

‘http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes’

as act

)

SELECT

FirstName,

LastName,

AdditionalContactInfo.query(

//act:eMail

Trang 9

)

FROM Person.Person

WHERE BusinessEntityID = 2

FOR XML RAW(‘ContactInfo’), ROOT(‘Contact’)

go

<Contact

xmlns:act=”http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes”>

<ContactInfo FirstName=”Catherine” LastName=”Abel”>

<act:eMail xmlns:act=”http://schemas.microsoft.com/sqlserver/2004/07/

adventure-works/ContactTypes”>

<act:eMailAddress>Joe@xyz.com</act:eMailAddress>

<act:SpecialInstructions>

Dont send emails for urgent issues Use telephone instead.

</act:SpecialInstructions>

</act:eMail>

</ContactInfo>

</Contact>

You can use WITH XMLNAMESPACESto declare namespaces for use in subsequent SELECT

statements Using this statement makes it possible to omit the prolog from the query() It

also has the desirable side effect of adding the actnamespace declaration to the root

Contactnode in the resulting FOR XML RAWwrapper It’s a great keystroke saver and helps

keepxmldata type queries readable

In addition to selecting nodes with simple XPath expressions, you can usequery()to

specifyWHEREclause conditions on the selected nodes, iterate through the nodes using

for-eachsemantics, order the nodes differently than in the original document, and

return XML in any desired structure, based on the selection This type of processing is

known by its acronym FLWOR (pronounced flower), which stands forfor,let,where,

order by,return

TheforClause The forclause establishes a variable that is bound to a node list for the

purpose of iterating over each node In each iteration of the forloop, this bound variable

takes the value of the context node It may be optionally typed (using as

XML_Schema_TypeName)to a schema-declared type, and it is followed by the XPath used to

match the nodes to be selected The bound variable in the following example is$ContextNode:

SELECT Instructions.query(‘

declare default element namespace

“http://schemas.microsoft.com/sqlserver/2004/07/adventure

-works/ProductModelManuInstructions”;

for $ContextNode in //Location

return

<LotSize>

{$ContextNode/@LotSize}

</LotSize>

Trang 10

‘) as Result

FROM Production.ProductModel

WHERE ProductModelID = 10

Go

<LotSize

xmlns=”http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions” LotSize=”100” />

This example also shows the use of thedeclare default element namespacestatement,

which allows the specified XPath expressions that follow it to omit any namespace prefixes

In place of an XPath expression, you can use the bound variable to iterate through a

sequence of values, rather than nodes, as in the following example:

SELECT Instructions.query(‘

for $ContextNode in (1, 2, 3)

return

<Number>

{$ContextNode }

</Number>

‘) as Result

FROM Production.ProductModel

WHERE ProductModelID = 10

go

<Number>1</Number>

<Number>2</Number>

<Number>3</Number>

You can also specify more than one bound variable in the forclause Bound variables

subsequent to the first can be used in XPath queries against the first In this manner, two

related context nodes—one inner and one outer—can be created simultaneously This is

analogous to writing a nested forloop in a programming language, but here you need

only declare both context variables by using a comma Here’s an example:

DECLARE @Xml xml

SET @Xml = ‘

<outernode name=”a”>

<innernode>1</innernode>

<innernode>2</innernode>

<innernode>3</innernode>

</outernode>

<outernode name=”b”>

<innernode>4</innernode>

<innernode>5</innernode>

<innernode>6</innernode>

</outernode>

SELECT @Xml.query(‘

Ngày đăng: 05/07/2014, 02:20

TỪ KHÓA LIÊN QUAN