TYPE-Direktive in FOR XML-Abfragen

In SQL Server 2000 wird das Ergebnis einer FOR XML-Abfrage immer direkt in Textform an den Client zurückgegeben. Ab SQL Server 2005 wird der XML-Datentyp von SQL Server unterstützt. Dadurch wird es Ihnen ermöglicht, durch Angeben der TYPE-Direktive optional anzufordern, dass das Ergebnis einer FOR XML-Abfrage als XML-Datentyp zurückgegeben wird. Dies ermöglicht Ihnen, das Ergebnis einer FOR XML-Abfrage auf dem Server zu verarbeiten. So können Sie beispielsweise eine XQuery dafür angeben, das Ergebnis einer Variablen vom Typ xml zuweisen oder Geschachtelte FOR XML-Abfragen dafür schreiben.

HinweisHinweis

SQL Server gibt Instanzdaten vom Datentyp xml als Ergebnis verschiedener Serverkonstrukte wie FOR XML-Abfragen, die die TYPE-Direktive verwenden, an den Client zurück, oder um XML-Instanzdatenwerte aus SQL-Tabellen und Ausgabeparametern zurückzugeben. Im Code der Clientanwendung erfordert der ADO.NET-Anbieter, dass die Informationen vom XML-Datentyp im Binärcode vom Server gesendet werden. Wenn Sie jedoch FOR XML ohne die TYPE-Direktive verwenden, werden die XML-Daten als Zeichenfolgentyp zurückgesendet. Der Clientanbieter ist in jedem Fall fähig, beide XML-Formate zu verarbeiten. Beachten Sie, dass FOR XML der obersten Ebene ohne die TYPE-Direktive nicht mit Cursorn verwendet werden kann.

Beispiele:

Die folgenden Beispiele veranschaulichen die Verwendung der TYPE-Direktive für FOR XML-Abfragen.

Abrufen von FOR XML-Abfrageergebnissen als XML-Typ

Die folgende Abfrage ruft Informationen zu Kundenkontakten aus der Contacts-Tabelle auf. In FOR XML ist die TYPE-Direktive angegeben, daher wird das Ergebnis als xml-Typ zurückgegeben.

SELECT ContactID, FirstName, LastName, Phone
FROM Person.Contact
ORDER BY ContactID
FOR XML AUTO, TYPE

Dies ist das Teilergebnis:

<Contact ContactID="1" FirstName="Syed" LastName="Abbas" 
         Phone="398-555-0132"/>
<Contact ContactID="2" FirstName="Catherine" LastName="Abel" 
         Phone="747-555-0171"/>
...

Zuweisen von FOR XML-Abfrageergebnissen zu einer Variablen vom Typ XML

Im folgenden Beispiel wird das Ergebnis einer FOR XML-Abfrage einer Variablen vom Typ xml, @x, zugewiesen. Die Abfrage ruft die Kontaktinformationen ContactID, FirstName, LastName sowie zusätzliche Telefonnummern aus der Spalte vom Typ xml, AdditionalContactInfo, ab. Die XML-Daten werden als xml-Typ zurückgegeben, da in der FOR XML-Klausel die TYPE-Direktive angegeben ist, und anschließend einer Variablen zugewiesen.

DECLARE @x XML
SET @x = (
   SELECT ContactID, 
          FirstName, 
          LastName, 
          AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
              //act:telephoneNumber/act:number') as MorePhoneNumbers
   FROM Person.Contact
   FOR XML AUTO, TYPE)
SELECT @x
GO

Abfragen von Ergebnissen einer FOR XML-Abfrage

FOR XML-Abfragen geben XML-Daten zurück. Folglich können Sie auf das von FOR XML-Abfragen zurückgegebene XML-Ergebnis Methoden vom Typ xml wie query() und value() anwenden.

In der folgenden Abfrage wird die query()-Methode vom Datentyp xml verwendet, um das Ergebnis einer FOR XML-Abfrage abzufragen. Weitere Informationen finden Sie unter query()-Methode (xml-Datentyp).

SELECT (SELECT ContactID, FirstName, LastName, AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
 //act:telephoneNumber/act:number
') as PhoneNumbers
FROM Person.Contact
FOR XML AUTO, TYPE).query('/Person.Contact[1]')

Die innere SELECT … FOR XML-Abfrage gibt ein Ergebnis vom Typ xml zurück, auf das das äußere SELECT die query()-Methode vom Typ xml anwendet. Beachten Sie, dass die TYPE-Direktive angegeben ist.

Dies ist das Ergebnis:

<Person.Contact ContactID="1" FirstName="Gustavo" LastName="Achong">
  <PhoneNumbers>
    <act:number xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">111-111-1111</act:number>
    <act:number xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">112-111-1111</act:number>
  </PhoneNumbers>
</Person.Contact>

In der folgenden Abfrage wird die value()-Methode vom Datentyp xml verwendet, um einen Wert aus dem XML-Ergebnis einer SELECT…FOR XML-Abfrage abzurufen. Weitere Informationen finden Sie unter value()-Methode (xml-Datentyp).

declare @FirstPhoneFromAdditionalContactInfo varchar(40);
SELECT @FirstPhoneFromAdditionalContactInfo = 
 ( SELECT ContactID, FirstName, LastName, AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";

   //act:telephoneNumber/act:number
   ') as PhoneNumbers
   FROM Person.Contact Contact
   FOR XML AUTO, TYPE).value('
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
  /Contact[@ContactID="1"][1]/PhoneNumbers[1]/act:number[1]', 'varchar(40)'
 )
select @FirstPhoneFromAdditionalContactInfo

Der XQuery-Pfadausdruck in der value()-Methode ruft die erste Telefonnummer des Kundenkontakts mit der ContactID 1 ab.

HinweisHinweis

Wenn die TYPE-Direktive nicht angegeben ist, wird das Ergebnis der FOR XML-Abfrage als nvarchar(max) zurückgegeben.

Verwenden von FOR XML-Abfrageergebnissen in INSERT-, UPDATE- und DELETE-Anweisungen (Transact-SQL-DML)

Das folgende Beispiel stellt dar, wie FOR XML-Abfragen in DML-Anweisungen (DML, Data Manipulation Language) verwendet werden können. In diesem Beispiel gibt die FOR XML-Abfrage eine Instanz vom Typ xml zurück. Die INSERT-Anweisung fügt diese XML-Daten in eine Tabelle ein.

CREATE TABLE T1(intCol int, XmlCol xml)
go
INSERT INTO T1 
VALUES(1, '<Root><ProductDescription ProductModelID="1" /></Root>')
go

CREATE TABLE T2(XmlCol xml)
go
INSERT INTO T2(XmlCol) 
SELECT (SELECT XmlCol.query('/Root') 
        FROM T1 
        FOR XML AUTO,TYPE) 
go