Abrufen von Resultsets in Datenströme

Anstelle des Empfangs von Ergebnissen im traditionellen Recordset-Objekt kann ADO Abfrageergebnisse auch in einen Datenstrom abrufen. Zum Aufnehmen dieser Ergebnisse kann das ADO-Objekt Stream (oder ein anderes Objekt mit Unterstützung der COM-Schnittstelle IStream, z. B. die ASP-Objekte Request und Response) verwendet werden. Dieses Feature kann beispielsweise verwendet werden, um Ergebnisse im XML-Format abzurufen. Mit SQL Server können XML-Ergebnisse z. B. auf unterschiedliche Weise zurückgegeben werden. Dies umfasst u. a. die Verwendung der FOR XML-Klausel mit einer SQL SELECT-Abfrage oder die Verwendung einer XPath-Abfrage.

Wenn Sie Abfrageergebnisse nicht in einem Recordset, sondern in einem Datenstromformat empfangen möchten, müssen Sie die adExecuteStream-Konstante aus ExecuteOptionEnum als Parameter der Execute-Methode eines Command-Objekts angeben. Wenn Ihr Anbieter dieses Feature unterstützt, werden die Ergebnisse bei der Ausführung in einem Datenstrom zurückgegeben. Möglicherweise müssen Sie zusätzliche anbieterspezifische Eigenschaften angeben, bevor der Code ausgeführt wird. Mit dem Microsoft OLE DB-Anbieter für SQL Server müssen beispielsweise Eigenschaften wie Output Stream in der Properties-Sammlung des Command-Objekts angegeben werden. Weitere Informationen zu SQL Server-spezifischen dynamischen Eigenschaften im Zusammenhang mit diesem Feature finden Sie in der SQL Server-Onlinedokumentation im Abschnitt zu XML-bezogenen Eigenschaften.

FOR XML-Beispielabfrage

Das folgende Beispiel ist in VBScript für die Northwind-Datenbank geschrieben:

<!-- BeginRecordAndStreamVBS -->  
<%@ LANGUAGE = VBScript %>  
<%  Option Explicit      %>  
  
<HTML>  
<HEAD>  
<META NAME="GENERATOR" Content="Microsoft Developer Studio"/>  
<META HTTP-EQUIV="Content-Type" content="text/html"; charset="iso-8859-1">  
<TITLE>FOR XML Query Example</TITLE>  
  
<STYLE>  
   BODY  
   {  
      FONT-FAMILY: Tahoma;  
      FONT-SIZE: 8pt;  
      OVERFLOW: auto  
   }  
  
   H3  
   {  
      FONT-FAMILY: Tahoma;  
      FONT-SIZE: 8pt;  
      OVERFLOW: auto  
   }  
</STYLE>  
  
<!-- #include file="adovbs.inc" -->  
<%  
   Response.Write "<H3>Server-side processing</H3>"  
  
   Response.Write "Page Generated @ " & Now() & "<BR/>"  
  
   Dim adoConn  
   Set adoConn = Server.CreateObject("ADODB.Connection")  
  
   Dim sConn  
   sConn = "Provider=SQLOLEDB;Data Source=" & _  
      Request.ServerVariables("SERVER_NAME") & ";" & _  
      Initial Catalog=Northwind;Integrated Security=SSPI;"  
  
   Response.write "Connect String = " & sConn & "<BR/>"  
  
   adoConn.ConnectionString = sConn  
   adoConn.CursorLocation = adUseClient  
  
   adoConn.Open  
  
   Response.write "ADO Version = " & adoConn.Version & "<BR/>"  
   Response.write "adoConn.State = " & adoConn.State & "<BR/>"  
  
   Dim adoCmd  
   Set adoCmd = Server.CreateObject("ADODB.Command")  
   Set adoCmd.ActiveConnection = adoConn  
  
   Dim sQuery  
   sQuery = "<ROOT xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:query>SELECT * FROM PRODUCTS WHERE ProductName='Gumbr Gummibrchen' FOR XML AUTO</sql:query></ROOT>"  
  
   Response.write "Query String = " & sQuery & "<BR/>"  
  
   Dim adoStreamQuery  
   Set adoStreamQuery = Server.CreateObject("ADODB.Stream")  
   adoStreamQuery.Open  
   adoStreamQuery.WriteText sQuery, adWriteChar  
   adoStreamQuery.Position = 0  
  
   adoCmd.CommandStream = adoStreamQuery  
   adoCmd.Dialect = "{5D531CB2-E6Ed-11D2-B252-00C04F681B71}"  
  
   Response.write "Pushing XML to client for processing "  & "<BR/>"  
  
   adoCmd.Properties("Output Stream") = Response  
   Response.write "<XML ID='MyDataIsle'>"  
   adoCmd.Execute , , 1024  
   Response.write "</XML>"  
  
%>  
  
<SCRIPT language="VBScript" For="window" Event="onload">  
   Dim xmlDoc  
   Set xmlDoc = MyDataIsle.XMLDocument  
   xmlDoc.resolveExternals=false  
   xmlDoc.async=false  
  
   If xmlDoc.parseError.Reason <> "" then  
      Msgbox "parseError.Reason = " & xmlDoc.parseError.Reason  
   End If  
  
   Dim root, child  
   Set root = xmlDoc.documentElement  
   For each child in root.childNodes  
      dim OutputXML  
      OutputXML = document.all("log").innerHTML  
      document.all("log").innerHTML = OutputXML & "<LI>" & child.getAttribute("ProductName") & "</LI>"  
   Next  
</SCRIPT>  
  
</HEAD>  
  
<BODY>  
  
   <H3>Client-side processing of XML Document MyDataIsle</H3>  
   <UL id=log>  
   </UL>  
  
</BODY>  
</HTML>  
<!-- EndRecordAndStreamVBS -->  
  

Die FOR XML-Klausel weist SQL Server an, Daten in Form eines XML-Dokuments zurückzugeben.

FOR XML-Syntax

FOR XML [RAW|AUTO|EXPLICIT]  

FOR XML RAW generiert generische Zeilenelemente mit Spaltenwerten als Attribute. FOR XML AUTO verwendet Heuristiken, um eine hierarchische Struktur mit Elementnamen zu generieren, die auf Tabellennamen basieren. FOR XML EXPLICIT generiert eine universelle Tabelle mit Beziehungen, die vollständig durch Metadaten beschrieben werden.

Nachfolgend ist eine SQL SELECT FOR XML-Beispielanweisung gezeigt:

SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO  

Der Befehl kann wie zuvor gezeigt in einer Zeichenfolge angegeben, CommandText zugewiesen oder in Form einer XML-Vorlagenabfrage angegeben werden, die CommandStream zugewiesen ist. Weitere Informationen zu XML-Vorlagenabfragen finden Sie unter Command-Datenströme in ADO oder in der SQL Server-Onlinedokumentation im Thema zur Verwendung von Datenströmen für die Befehlseingabe.

Als XML-Vorlagenabfrage wird die FOR XML-Abfrage wie folgt angezeigt:

<sql:query> SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO </sql:query>  

In diesem Beispiel wird das ASP-Objekt Response für die Output Stream-Eigenschaft angegeben:

adoCmd.Properties("Output Stream") = Response  

Anschließend geben Sie den adExecuteStream-Parameter von Execute an. In diesem Beispiel wird der Datenstrom in XML-Tags umschlossen, um eine XML-Dateninsel zu erstellen:

Response.write "<XML ID=MyDataIsle>"  
adoCmd.Execute , , adExecuteStream  
Response.write "</XML>"  

Bemerkungen

An diesem Punkt wurden die XML-Daten an den Clientbrowser gestreamt und können angezeigt werden. Zu diesem Zweck wird clientseitiges VBScript verwendet, um das XML-Dokument an eine DOM-Instanz zu binden und zum Erstellen einer Produktliste in HTML jeden untergeordneten Knoten zu durchlaufen.