Если нужно читать данные порциями, а не целиком, как
это сделано в примере, воспользуйтесь методом GetBytes, который аналогичен
ADO-методу GetChunk. Однако если объем данных очень велик, это не сильно
поможет, так как они передаются клиенту все сразу в момент вызова метода Read.
Для того чтобы данные передавались на клиента только по запросу, необходимо
передать в качестве параметра метода ExecuteReader флаг
CommandBehavior.SequentialAccess. В этом случае данные будут считываться
непосредственно в момент вызова GetBytes.
ПРИМЕЧАНИЕ
Для этого флага есть одно замечание.
Если вы выбираете несколько полей, считывать их значения вы должны в той
последовательности, в которой они возвращаются из базы. Видимо поэтому флаг
называется «Последовательный доступ».
Я знаю, что многие не любят хранимые процедуры.
Действительно, для использования хранимых процедур вы должны быть более-менее
знакомы с T-SQL и знать общие принципы работы с реляционными БД. Кроме этого, считается, что архитектура, в которой слишком большой упор сделан на вынесение
логики на уровень SQL Server-а, имеет ряд недостатков: плохое масштабирование, сложное сопровождение и отладка. Отчасти все это правда, однако лично я все же
стараюсь использовать хранимые процедуры везде, где возможно, и лишь в тех
случаях, когда бизнес-логика действительно сложна и требует взаимодействия
нескольких бизнес-компонентов, отказываюсь от их использования. Тем, кто не
хочет использовать хранимые процедуры для обновления больших объектов, я
советую прочитать статью http://support.microsoft.com/default.aspx?scid=kb;en-us;Q309158&ID=kb;en-us;Q309158, в которой излагается метод чтения и записи больших объектов с помощью DataSet.
Последнее, на чем я бы хотел остановиться, и что
вызывает наибольшее количество проблем у начинающих программистов это работа с
большими объектами в Oracle. Традиционно этот вопрос довольно сложен: в
про-дотнетовскую эру доступ к СУБД Oracle с помощью OLEDB-провайдеров в
основном обеспечивали две библиотеки: MSDAORA и OraOLEDB.
Провайдер MSDAORA – предоставлял слабый сервис (нельзя
было, например, узнать количество строк в выборке) и не позволял работать с
большими объектами в принципе. Единственным достоинством данного провайдера
является то, что он входит в стандартный пакет MDAC – Microsoft Data Access
Components.
Провайдер OraOLEDB – родной провайдер, который
предоставлял большую функциональность, чем MSDAORA, и позволял работать с
большими объектами.
ПРИМЕЧАНИЕ
В Oracle, как и в MS SQL, большие
текстовые данные отличаются от больших бинарных данных. Первые называются CLOB и NCLOB –
Character Large OBjects, вторые – BLOB – Binary
Large OBjects. Аналогию с типами MS SQL
провести несложно.
Получать и изменять данные с помощью объекта Recordset
можно точно так же, как и в случае MS SQL Server-а. Пример я приводил выше. Единственная
проблема связана с передачей больших объектов в качестве параметров хранимых
процедур. Для того чтобы это работало, необходимо в объекте Command установить
динамический параметр SPPrmsLOB в TRUE.
Я не буду подробно и с примерами останавливаться на
работе с этими провайдерами, вместо этого сосредоточившись на управляемом
ADO.NET провайдере. Если у вас будут вопросы, обратитесь к документации или, если совсем плохо будет, задайте вопрос в нашем форуме по базам данных.
Провайдер для ADO.NET не поставляется с .NET Framework
1.0, его нужно устанавливать вручную. Скачать последнюю версию можно по адресу http://www.microsoft.com/downloads/details.aspx?familyid=4f55d429-17dc-45ea-bfb3-076d1c052524&languageid=f49e8428-7071-4979-8a67-3cffcb0c2524&displaylang=en.
Вводную информацию об использовании этого провайдера в
ASP.NET-приложениях можно получить из статьи http://msdn.microsoft.com/vstudio/using/building/default.aspx?pull=/library/en-us/dndotnet/html/manprooracperf.asp.
Следующий пример демонстрирует методы работы с
большими объектами с помощью управляемого провайдера. Для его правильной работы
вам необходимо подключить сборку System.Data.OracleClient.dll.
Sub FillDBFromStream(stream as Stream, UserName as String)
'Открываем
соединение
Dim con As New OracleClient.OracleConnection("server=srv;Uid=u;pwd=p")
'Создаем запрос с одним параметром username
Dim da As New
OracleClient.OracleDataAdapter("select *
from USERS_STATE where
USERNAME = :username", con)