Извлечение результирующих наборов в потоки
Вместо получения результатов в традиционном объекте Recordset ADO может получить результаты запроса в потоке. Для хранения этих результатов можно использовать объект ADO Stream (или другие объекты, поддерживающие интерфейс COM IStream , например объекты ASP Request и Response ). Одним из способов использования этой функции является получение результатов в формате XML. Например, при использовании SQL Server результаты XML можно возвращать несколькими способами, например с помощью предложения FOR XML с SQL-запросом SELECT или запроса XPath.
Чтобы получить результаты запроса в потоковом формате, а не в Recordset, необходимо указать константу adExecuteStream из ExecuteOptionEnum в качестве параметра метода Execute объекта Command . Если поставщик поддерживает эту функцию, результаты будут возвращены в потоке после выполнения. Перед выполнением кода может потребоваться указать дополнительные свойства, зависящие от поставщика. Например, для поставщика Microsoft OLE DB для SQL Server необходимо указать такие свойства, как Выходной поток в коллекции Properties объекта Command. Дополнительные сведения о SQL Server динамических свойствах, связанных с этой функцией, см. в разделе Свойства XML-Related электронной документации по SQL Server.
Пример запроса FOR XML
Следующий пример записывается на VBScript в базу данных 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 -->
Предложение FOR XML указывает SQL Server возвращать данные в виде XML-документа.
Синтаксис FOR XML
FOR XML [RAW|AUTO|EXPLICIT]
FOR XML RAW создает универсальные элементы строк, которые имеют значения столбцов в качестве атрибутов. FOR XML AUTO использует эвристические методы для создания иерархического дерева с именами элементов на основе имен таблиц. FOR XML EXPLICIT создает универсальную таблицу со связями, полностью описанными в метаданных.
Ниже приведен пример инструкции SQL SELECT FOR XML:
SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO
Команду можно указать в строке, как показано ранее, назначить CommandText или в виде запроса шаблона XML, назначенного CommandStream. Дополнительные сведения о запросах шаблонов XML см. в разделах Потоки команд в ADO или Использование потоков для ввода команд в электронной документации по SQL Server.
В качестве запроса шаблона XML запрос FOR XML выглядит следующим образом:
<sql:query> SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO </sql:query>
В этом примере указывается объект ОТВЕТА ASP для свойства Output Stream :
adoCmd.Properties("Output Stream") = Response
Затем укажите параметр adExecuteStreamдля параметра Execute. В этом примере поток упаковывается в xml-теги для создания острова XML-данных:
Response.write "<XML ID=MyDataIsle>"
adoCmd.Execute , , adExecuteStream
Response.write "</XML>"
Комментарии
На этом этапе XML-код передается в клиентский браузер и готов к отображению. Для этого используется клиентский VBScript для привязки XML-документа к экземпляру модели DOM и циклического перебора каждого дочернего узла для создания списка продуктов в HTML.