Récupération d’ensembles de résultats dans des flux
Au lieu de recevoir des résultats dans l’objet Recordset traditionnel, ADO peut plutôt récupérer les résultats de requête dans un flux. L'objet Stream ADO (ou d'autres objets qui prennent en charge l'interface IStream COM, tels que les objets Request et Response ASP) peut être utilisé pour contenir ces résultats. L’une des utilisations de cette fonctionnalité consiste à récupérer les résultats au format XML. Avec SQL Server, par exemple, les résultats XML peuvent être retournés de plusieurs façons, comme l’utilisation de la clause FOR XML avec une requête SQL SELECT ou l’utilisation d’une requête XPath.
Pour recevoir des résultats de requête au format de flux au lieu d’un Recordset, vous devez spécifier la constante adExecuteStream de ExecuteOptionEnum comme paramètre de la méthode Execute d’un objet Command. Si votre fournisseur prend en charge cette fonctionnalité, les résultats sont retournés dans un flux lors de l’exécution. Vous devrez peut-être spécifier des propriétés supplémentaires spécifiques au fournisseur avant l’exécution du code. Par exemple, avec le fournisseur Microsoft OLE DB pour SQL Server, les propriétés telles que flux de sortie dans la collection Properties de l’objet Command doivent être spécifiées. Pour plus d’informations sur les propriétés dynamiques spécifiques à SQL Server liées à cette fonctionnalité, consultez XML-Related Propriétés dans la documentation en ligne de SQL Server.
Exemple de requête FOR XML
L’exemple suivant est écrit en VBScript dans la base de données Northwind :
<!-- 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 -->
La clause FOR XML indique à SQL Server de retourner des données sous la forme d’un document XML.
Syntaxe FOR XML
FOR XML [RAW|AUTO|EXPLICIT]
FOR XML RAW génère des éléments de ligne génériques qui ont des valeurs de colonne en tant qu’attributs. FOR XML AUTO utilise des heuristiques pour générer une arborescence hiérarchique avec des noms d’éléments basés sur des noms de tables. FOR XML EXPLICIT génère une table universelle avec des relations entièrement décrites par les métadonnées.
Voici un exemple d’instruction SQL SELECT FOR XML :
SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO
La commande peut être spécifiée dans une chaîne, comme indiqué précédemment, affectée à CommandText, ou sous la forme d’une requête de modèle XML affectée à CommandStream. Pour plus d'informations sur les requêtes de modèle XML, consultez flux de commandes dans la documentation ADO ou Utilisation de flux pour l'entrée de commandes dans la documentation en ligne de SQL Server.
En tant que requête de modèle XML, la requête FOR XML s’affiche comme suit :
<sql:query> SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO </sql:query>
Cet exemple spécifie l’objet asp Response pour la propriété Output Stream :
adoCmd.Properties("Output Stream") = Response
Ensuite, spécifiez le paramètre adExecuteStream pour Exécuter. Cet exemple encapsule le flux dans les balises XML pour créer une île de données XML :
Response.write "<XML ID=MyDataIsle>"
adoCmd.Execute , , adExecuteStream
Response.write "</XML>"
Remarques
À ce stade, le code XML a été diffusé en continu vers le navigateur client et il est prêt à être affiché. Pour ce faire, utilisez VBScript côté client pour lier le document XML à une instance du DOM et effectuer une boucle dans chaque nœud enfant pour générer une liste de produits en HTML.