Recupero di insiemi di risultati in flusso
Anziché ricevere risultati nel oggetto Record set tradizionale, ADO può invece recuperare i risultati della query in un flusso. L'oggetto ADO Stream (o altri oggetti che supportano l'interfaccia COM IStream, come l'oggetto ASP Request e l'oggetto ASP Response) può essere usato per contenere questi risultati. Un uso di questa funzionalità consiste nel recuperare i risultati in formato XML. Con SQL Server, ad esempio, i risultati XML possono essere restituiti in diversi modi, ad esempio usando la clausola FOR XML con una query SQL SELECT o usando una query XPath.
Per ricevere i risultati della query in formato flusso anziché in un Recordset, è necessario specificare la costante adExecuteStream dall' ExecuteOptionEnum come parametro del metodo Execute di un oggetto Command. Se il provider supporta questa funzionalità, i risultati verranno restituiti in un flusso al momento dell'esecuzione. Potrebbe essere necessario specificare proprietà aggiuntive specifiche del provider prima dell'esecuzione del codice. Ad esempio, con il provider Microsoft OLE DB per SQL Server, è necessario specificare proprietà come flusso di outputnell'insieme Properties dell'oggetto Command. Per altre informazioni sulle proprietà dinamiche specifiche di SQL Server correlate a questa funzionalità, vedere XML-Related Proprietà nella documentazione online di SQL Server.
Esempio di query FOR XML
L'esempio seguente è scritto in VBScript nel database 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 clausola FOR XML indica a SQL Server di restituire dati sotto forma di documento XML.
Sintassi FOR XML
FOR XML [RAW|AUTO|EXPLICIT]
FOR XML RAW genera elementi di riga generici con valori di colonna come attributi. FOR XML AUTO usa euristica per generare un albero gerarchico con nomi di elemento basati sui nomi delle tabelle. FOR XML EXPLICIT genera una tabella universale con relazioni completamente descritte dai metadati.
Di seguito è riportato un esempio di istruzione SQL SELECT FOR XML:
SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO
Il comando può essere specificato in una stringa come illustrato in precedenza, assegnato a CommandTexto sotto forma di query modello XML assegnata a CommandStream. Per ulteriori informazioni sulle query con modelli XML, consultare Flussi di comandi in ADO oppure utilizzare i flussi per l'input dei comandi nella documentazione online di SQL Server.
Come in una query modello XML, la query FOR XML risulta come segue:
<sql:query> SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO </sql:query>
In questo esempio viene specificato l'oggetto ASP Response per la proprietà Output Stream:
adoCmd.Properties("Output Stream") = Response
Quindi, specificare il parametro adExecuteStream di Execute. In questo esempio viene eseguito il wrapping del flusso in tag XML per creare un'isola di dati XML:
Response.write "<XML ID=MyDataIsle>"
adoCmd.Execute , , adExecuteStream
Response.write "</XML>"
Osservazioni
A questo punto, il codice XML è stato trasmesso al browser client ed è pronto per essere visualizzato. Per fare ciò, usa VBScript sul lato client per associare il documento XML a un'istanza del DOM e iterare attraverso ogni nodo figlio per creare un elenco di Prodotti in HTML.