Recuperando conjuntos de resultados em fluxos
Em vez de receber resultados no objeto recordset tradicional, o ADO pode recuperar os resultados da consulta em um fluxo. O objeto Stream do ADO (ou outros objetos que dão suporte à interface COM IStream, como os objetos Request e Response do ASP) pode ser usado para conter esses resultados. Um uso para esse recurso é recuperar resultados no formato XML. Com o SQL Server, por exemplo, os resultados XML podem ser retornados de várias maneiras, como usar a cláusula FOR XML com uma consulta SQL SELECT ou usar uma consulta XPath.
Para receber os resultados da consulta no formato de fluxo em vez de em um Recordset, especifique a constante adExecuteStream do ExecuteOptionEnum como um parâmetro do método Execute de um objeto Command. Se o provedor der suporte a esse recurso, os resultados serão retornados em um fluxo após a execução. Talvez seja necessário especificar propriedades adicionais específicas do provedor antes que o código seja executado. Por exemplo, com o Provedor OLE DB da Microsoft para SQL Server, propriedades como Fluxo de Saída na coleção de propriedades do objeto Command devem ser especificadas. Para obter mais informações sobre propriedades dinâmicas específicas do SQL Server relacionadas a esse recurso, consulte XML-Related Propriedades nos Manuais Online do SQL Server.
Exemplo de consulta FOR XML
O exemplo a seguir é escrito em VBScript no banco de dados 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 -->
A cláusula FOR XML instrui o SQL Server a retornar dados na forma de um documento XML.
Sintaxe FOR XML
FOR XML [RAW|AUTO|EXPLICIT]
FOR XML RAW gera elementos de linha genéricos que têm valores de coluna como atributos. FOR XML AUTO usa heurística para gerar uma árvore hierárquica com nomes de elementos baseados em nomes de tabela. FOR XML EXPLICIT gera uma tabela universal com relações totalmente descritas por metadados.
Um exemplo de instrução SQL SELECT FOR XML segue:
SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO
O comando pode ser especificado em uma cadeia de caracteres, conforme mostrado anteriormente, atribuído a CommandTextou na forma de uma consulta de modelo XML atribuída a commandstream. Para obter mais informações sobre consultas de modelo XML, consulte fluxos de comando no ADO ou o uso de fluxos para entrada de comandos nos Manuais Online do SQL Server.
Como uma consulta de modelo XML, a consulta FOR XML é exibida da seguinte maneira:
<sql:query> SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO </sql:query>
Este exemplo especifica o objeto de Resposta ASP para a propriedade do Fluxo de Saída:
adoCmd.Properties("Output Stream") = Response
Em seguida, especifique parâmetro adExecuteStream de Execute. Este exemplo encapsula o fluxo em marcas XML para criar uma ilha de dados XML:
Response.write "<XML ID=MyDataIsle>"
adoCmd.Execute , , adExecuteStream
Response.write "</XML>"
Observações
Neste ponto, o XML foi transmitido para o navegador do cliente e está pronto para ser exibido. Isso é feito usando o VBScript do lado do cliente para associar o documento XML a uma instância do DOM e percorrendo cada nó filho para construir uma lista de produtos em HTML.