Иерархические строки часто структурированы как несколько наборов связанных строк. Для большей эффективности зачастую лучше извлекать несколько наборов строк за одно обращение к базе данных, чем по отдельности запрашивать каждый из них. Обычно для этого выполняется пакет SQL-выражений (batch of SQL expressions) или хранимая процедура с несколькими выражениями SELECT. Кроме того, если вы используете в операторе SELECT блок FOR XML, SQL Server 2000 возвращает иерархические строки в виде XML.
Применение ADO.NET-объекта DataReader
В следующем примере исполняется пакет из двух SQL-выражений SELECT и соответствующие наборы результатов (result sets) извлекаются через объект DataReader. Этот объект обеспечивает навигацию по данным в направлении только вперед, так что для дальнейшей работы данные скорее всего следует перенести в другой контейнер. Так как DataReader оставляет соединение с базой данной открытым, с точки зрения масштабируемости данные надо переносить быстро и как можно скорее закрывать соединение. Передавать объект DataReader между уровнями распределенного приложения нельзя.
Для перебора строки в наборах результатов применяются методы NextResult и Read объекта DataReader.
Dim sqlCmd As SQLCommand
Dim sqlDataRdr As SQLDataReader
Dim fld As Integer
Dim rptLine As String
Try
' Подготовить объект команды, исполняющий хранимую процедуру,
' которая возвращает Orders и OrderDetails
sqlCmd = New SQLCommand()
With sqlCmd
.CommandType = CommandType.StoredProcedure
.CommandText = "GetOrders"
.Connection = New SqlConnection(myConnString)
End With
' Открыть соединение
sqlCmd.Connection.Open()
' Выполнить команду; результат передается в DataReader
sqlDataRdr = sqlCmd.ExecuteReader()
' Перебирать строки в первом наборе результатов
Do
While (sqlDataRdr.Read)
' Здесь со строкой можно выполнить какие-либо действия
rptLine = ""
For fld = 0 To sqlDataRdr.FieldCount - 1
rptLine = rptLine & sqlDataRdr.Item(fld).ToString
If fld < sqlDataRdr.FieldCount - 1 Then
rptLine = rptLine & ", "
End If
Next
End While
' Переместить указатель на следующий набор результатов
If Not (sqlDataRdr.NextResult) Then
Exit Do
End If
Loop
Catch E As Exception
Finally
' Закрыть DataReader
sqlDataRdr.Close()
End Try
Применение XmlReader и ADO.NET-объекта SqlCommand
В Microsoft SQL Server 2000 встроена поддержка XML. Чтобы результаты выражений SELECT возвращались в виде XML, в этих выражениях нужно указывать блок FOR XML. Метод ExecuteXmlReader объекта SQLCommand позволяет получать XML-данные напрямую от SQL Server 2000. ExecuteXmlReader возвращает объект System.Xml.XmlReader, содержащий XML-данные, полученные от SQL Server 2000.
В следующем примере хранимая процедура, использующая FOR XML, запускается вызовом метода ExecuteXmlReader объекта SQLCommand.
Dim sqlConn As SqlConnection
Dim sqlCmd As SqlCommand
Dim xmlRdr As XmlReader
Try
' Создать новый объект соединения
sqlConn = New SqlConnection(myConnString)
' Создать новый объект команды
sqlCmd = New SqlCommand()
' Указать исполняемую команду
With sqlCmd
.CommandType = CommandType.StoredProcedure
.CommandText = "GetOrdersXML"
.Connection = sqlConn
End With
' Открыть соединение
sqlConn.Open()
' Выполнить команду и извлечь строку в DataReader
xmlRdr = sqlCmd.ExecuteXmlReader()
' Перейти к корневому элементу
xmlRdr.MoveToContent()
' Что-то делаем с данными
outXML = xmlRdr.ReadOuterXml
' Перейти к следующему элементу
xmlRdr.MoveToElement()
' Считать атрибут OrderId текущего элемента
xmlRdr.MoveToAttribute("OrderId")
…
Catch e As Exception
' Обработать исключение
Finally
sqlConn.Close()
End Try