Поделиться через


Получение результирующих наборов данных в виде потоков

Вместо получения результатов в традиционном объекте Recordset ADO может вместо этого получить результаты запроса в поток. Объект ADO Stream (или другие объекты, поддерживающие интерфейс COM IStream, например запроса ASP и объекты response) можно использовать для хранения этих результатов. Одним из способов использования этой функции является получение результатов в формате XML. Например, при использовании SQL Server результаты XML можно возвращать несколькими способами, например с помощью предложения FOR XML с запросом SQL SELECT или с помощью запроса XPath.

Чтобы получить результаты запроса в формате потока, а не в Recordset, необходимо указать константу adExecuteStream из ExecuteOptionEnum в качестве параметра метода Execute для объекта Command. Если поставщик поддерживает эту функцию, результаты будут возвращены в потоке после выполнения. Перед выполнением кода может потребоваться указать дополнительные свойства, относящиеся к поставщику. Например, с поставщиком Microsoft OLE DB для SQL Server, свойства, такие как поток вывода, в коллекции Свойства объекта 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 Books Online.

В качестве запроса XML-шаблона запрос FOR XML отображается следующим образом:

<sql:query> SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO </sql:query>  

В этом примере задается объект ответа ASP для свойства потока вывода :

adoCmd.Properties("Output Stream") = Response  

Затем укажите параметр adExecuteStreamExecute. В этом примере поток упаковывается в XML-теги для создания острова данных XML:

Response.write "<XML ID=MyDataIsle>"  
adoCmd.Execute , , adExecuteStream  
Response.write "</XML>"  

Замечания

На этом этапе XML был отправлен на клиентский браузер и готов к отображению. Это делается с помощью клиентского VBScript для привязки XML-документа к экземпляру DOM и циклического прохождения по каждому дочернему узлу для создания списка продуктов в HTML.