• Aucun résultat trouvé

Things to Watch Out For

Dans le document SQL Server (Page 188-193)

In dealing with XML, it is possible to have attributes and elements with the same name. For example, the following is perfectly acceptable in XML:

<Employee>

To test this, run the following query:

DECLARE @test xml

When you run this query, you get the XML shown at the beginning of this section. However, the follow-ing query generates an error tryfollow-ing to deal with the same-name columns:

SELECT Contact.ContactID,

SalesOrderHeader.SalesOrderID, SalesOrderHeader.ContactID, Contact.FirstName

FROM Sales.SalesOrderHeader, Person.Contact

WHERE SalesOrderHeader.ContactID = Contact.ContactID AND Contact.ContactID = 218

FOR XML RAW, XMLSCHEMA

The solution to this is to simply add the ELEMENTSdirective to the FOR XMLstatement, like so:

SELECT Contact.ContactID,

SalesOrderHeader.SalesOrderID, SalesOrderHeader.ContactID, Contact.FirstName

FROM Sales.SalesOrderHeader, Person.Contact

WHERE SalesOrderHeader.ContactID = Contact.ContactID AND Contact.ContactID = 218

FOR XML RAW, XMLSCHEMA, ELEMENTS

It is important to remember that using the XSINILdirective is permitted when generating schemas. If a column returns a NULLvalue it is not included in the schema if the directive is not included. Adding the XSINILdirective ensures that both columns are returned in the results, as well as included in the schema. The following example illustrates this:

SELECT Contact.ContactID,

SalesOrderHeader.SalesOrderID, SalesOrderHeader.ContactID, Contact.FirstName

Contact.MiddleName

FROM Sales.SalesOrderHeader, Person.Contact

WHERE SalesOrderHeader.ContactID = Contact.ContactID AND Contact.ContactID = 226

FOR XML RAW, XMLSCHEMA, ELEMENTS XSINIL

The example specifies that if any values returned from the query are found, to still include an element for that value. In this example, the MiddleName column does not have a value, but the column is still included with the following value:

<MiddleName xsi:nil=”true” />

That covers the FOR XMLchanges. Microsoft made a number of OPENXMLchanges as well, so on to that.

OPENXML

Two improvements were made to the OPENXMLclause in SQL Server 2005. The first is the capability to pass an xmldata type to the sp_xml_preparedocument stored procedure. The second enhancement is the capability to use the new data types in the WITHclause.

In the following example, the @xmlvarvariable is declared as an xmldata type and filled with an XML document, which is then passed to the sp_xml_preparedocumentstored procedure. The OPENXML statement is then used to query the XML document to retrieve the Employeeattribute of all three employees:

DECLARE @xmldocDoc int DECLARE @xmlvar xml SET @xmlvar = N’<ROOT>

<Employee EmployeeID=”1” ManagerID=”2” NationalIDNumber=”10708100”>

<Tenor Position=”AltoTenor” Solo=”Io Conosco un Giardino”>

<FirstName>José</FirstName>

<LastName>Carreras</LastName>

</Tenor>

</Employee>

<Employee EmployeeID=”2” ManagerID=”3” NationalIDNumber=”112432117”>

<Tenor Position=”BaritoneTenor” Solo=”Memories de Danton”>

<FirstName>Plácido</FirstName>

-- Create an internal representation of the XML document.

EXEC sp_xml_preparedocument @xmldocDoc OUTPUT, @xmlvar -- Execute a SELECT statement using OPENXML rowset provider.

SELECT *

The results of the SELECTstatement are shown in Figure 8-23.

Figure 8-23

The example demonstrates both enhancements to the OPENXMLstatement by passing an xmldata type variable to the sp_xml_preparedocumentstored procedure, and by using the new data types in the WITHclause.

Finally, make the following modifications to the example code:

DECLARE @xmldocDoc int DECLARE @xmlvar xml SET @xmlvar = N’<ROOT>

<Employee EmployeeID=”1” ManagerID=”2” NationalIDNumber=”10708100”>

<Tenor Position=”AltoTenor” Solo=”Io Conosco un Giardino”>

<FirstName>José</FirstName>

<LastName>Carreras</LastName>

</Tenor>

</Employee>

<Employee EmployeeID=”2” ManagerID=”3” NationalIDNumber=”112432117”>

<Tenor Position=”BaritoneTenor” Solo=”Memories de Danton”>

<FirstName>Plácido</FirstName>

-- Create an internal representation of the XML document.

EXEC sp_xml_preparedocument @xmldocDoc OUTPUT, @xmlvar -- Execute a SELECT statement using OPENXML rowset provider.

SELECT *

FROM OPENXML (@xmldocDoc, ‘/ROOT/Employee/Tenor’,1) WITH (Position varchar(15),

Solo varchar(15))

EXEC sp_xml_removedocument @xmldocDoc

Now rerun the query. You should see results similar to those shown in Figure 8-24.

Figure 8-24

Using the OPENXMLclause to go deeper into the XML document, the Positionand Soloattributes were queried and returned, as displayed in the figure.

Summar y

In this chapter, you learned about the new improvements to the FOR XMLand OPENXMLstatements. The FOR XMLstatement comes packed with a lot of new functionality that makes shaping your data and cre-ating XML instances much easier.

The PATHmode, as you learned, is much easier to learn than the EXPLICITmode, and the results are just as pleasing with a lot shorter learning curve. The TYPEdirective is a very nice addition as well, giv-ing you the option of returngiv-ing the query results as an xmldata type, with very little restriction. The enhancements to the RAWand AUTOmodes, specifically the capability to specify the root element, return element-centric XML, and specify the row element name come in very useful when you want to deter-mine the shape of your XML results.

Of all the excellent features in this chapter, the two most important are the capability to automatically generate schemas and nesting FOR XMLqueries. These two alone should make any developer’s life infinitely easier, and probably should put the EXPLICITmode out of business.

Not as many enhancements were made to OPENXML, but the few that were made were very nice, such as the addition of a capability to pass xmldata type to the sp_xml_preparedocumentstored procedure.

The next chapter discusses CLR enhancements in SQL Server 2005 and how those enhancements benefit you when dealing with XML in SQL Server.

CLR Suppor t in

Dans le document SQL Server (Page 188-193)