Recuperar conjuntos de resultados en secuencias
En lugar de recibir resultados en el objeto Recordset tradicional, ADO puede recuperar los resultados de la consulta en una secuencia. El objeto ADO Stream (u otros objetos que soporten la interfaz COM IStream, como los objetos ASP Request y Response) puede utilizarse para contener estos resultados. Un uso de esta característica es recuperar los resultados en formato XML. Con SQL Server, por ejemplo, los resultados XML se pueden devolver de varias maneras, como el uso de la cláusula FOR XML con una consulta SELECT de SQL o mediante una consulta XPath.
Para recibir los resultados de la consulta en formato de secuencia en lugar de en un objeto Recordset, debe especificar la constante adExecuteStream de ExecuteOptionEnum como parámetro del método Execute de un objeto Command. Si el proveedor admite esta característica, los resultados se devolverán en una secuencia tras la ejecución. Es posible que tenga que especificar propiedades específicas del proveedor adicionales antes de que se ejecute el código. Por ejemplo, con el proveedor OLE DB de Microsoft para SQL Server, se deben especificar propiedades como Flujo de salida en la colección Properties del objeto Command. Para obtener más información sobre las propiedades dinámicas específicas de SQL Server relacionadas con esta característica, Propiedades relacionadas con XML en los Libros en pantalla de Microsoft SQL Server.
Ejemplo de consulta FOR XML
El ejemplo siguiente se escribe en VBScript en la base de datos 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 cláusula FOR XML indica a SQL Server que devuelvan datos en forma de documento XML.
Sintaxis FOR XML
FOR XML [RAW|AUTO|EXPLICIT]
FOR XML RAW genera elementos de fila genéricos que tienen valores de columna como atributos. FOR XML AUTO usa heurística para generar un árbol jerárquico con nombres de elemento basados en nombres de tabla. FOR XML EXPLICIT genera una tabla universal con relaciones completamente descritas por metadatos.
A continuación se muestra un ejemplo de instrucción SQL SELECT FOR XML:
SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO
El comando se puede especificar en una cadena como se muestra anteriormente, asignada a CommandText o en forma de una consulta de plantilla XML asignada a CommandStream. Para obtener más información sobre las consultas de plantillas XML, vea Flujos de comandos en ADO o Uso de secuencias para la entrada de comandos en los libros en pantalla de Microsoft SQL Server.
Como consulta de plantilla XML, la consulta FOR XML aparece de la siguiente manera:
<sql:query> SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO </sql:query>
En este ejemplo se especifica el objeto ASP Response para la propiedad flujo de salida:
adoCmd.Properties("Output Stream") = Response
A continuación, especifique el parámetro adExecuteStream de Execute. En este ejemplo se ajusta la secuencia en etiquetas XML para crear una isla de datos XML:
Response.write "<XML ID=MyDataIsle>"
adoCmd.Execute , , adExecuteStream
Response.write "</XML>"
Comentarios
En este momento, se ha transmitido XML al explorador cliente y está listo para mostrarse. Esto se hace mediante VBScript del lado cliente para enlazar el documento XML a una instancia del DOM y recorrer en bucle cada nodo secundario para crear una lista de productos en HTML.