Номер статьи: KB000016
Связанные блоки:
Есть несколько вариантов выполнения запросов к БД в пользовательском приложении: через стандартные программные интерфейсы или через объект репозитория «Запрос».
Первый вариант предполагает выполнение запроса через интерфейсы сборки Dal. Если используется сложный по структуре запрос, то данный метод имеет ряд недостатков:
увеличивается трудоемкость редактирования запроса;
ухудшается «читабельность» кода пользовательского приложения.
Рассмотрим пример выполнения параметрического запроса, которые добавляет запись в какую-либо таблицу базы данных. Значения полей передаются посредством входных параметров функции. Для выполнения примера предполагается наличие в репозитории объекта «База данных» с идентификатором «OBJ_DB». Результатом работы функции будет количество добавленных записей.
Пример извлечения значений. Результатом работы функции будет являться курсор с результирующим набором данных.
Второй вариант предполагает использование объекта репозитория «Запрос» с необходимым параметром. В приложении должна быть функция, позволяющая получать результат выполнения этого запроса. Преимущества данного способа:
запрос хранится в определенном месте и его можно легко его редактировать;
уменьшается количество кода прикладного приложения, увеличивается эффективность его отладки.
Пример получения данных путем выполнения объекта «Запрос». Идентификатор запроса в репозитории передается в параметре функции QueryId, идентификатор параметра запроса - ParamId, значение параметра - ParamValue. Результатом работы функции будет открытый экземпляр объекта, предоставляющий доступ к кэшированным данными.
В приложении код будет выглядеть следующим образом:
Var
Tasks: IDatasetInstance;
Begin
Tasks := RunQueryWithParam(< Идентификатор запроса >, "ID", < Значение параметра >);
Для получения доступа к данным можно использовать свойство IDatasetInstance.FieldsIDatasetInstance.Fields, либо обратиться к кэшу источника посредством метода IDatasetInstance.OpenCached:
Var
Tasks: IDatasetInstance;
TasksData: ICachedDataset;
Begin
Tasks := RunQueryWithParam(< Идентификатор запроса >, "ID", < Значение параметра >);
TasksData := Tasks.OpenCached;
Для передачи параметру множественного значения можно использовать следующую конструкцию:
Var
Tasks: IDatasetInstance;
Ls: ArrayList;
Begin
Ls := New ArrayList.Create;
For i := 1 To 2 Do
Ls.Add(i);
End For;
Tasks := RunQueryWithParam(< Идентификатор запроса >, "ID", Ls.ToArray);
Настройки серверов СУБД накладывают ограничение на количество одновременно открытых курсоров, поэтому необходимо своевременно закрывать неиспользуемые курсоры с помощью метода Close.
При реализации поддержки драйверов Microsoft SQL Server 2008 был задействован режим работы MARS (Multiple Active Result Set). Использование данного режима позволяет в рамках одного соединения иметь более одного открытого результирующего набора данных. Однако, пока данные одного результирующего набора не дочитаны до конца, то невозможно начать новую транзакцию в рамках этого соединения. Для решение данной проблемы существует два варианта решения:
Использовать разные соединения. Для этого можно создать разные объекты «База данных» в репозитории, либо создавать подключение непосредственно в прикладном коде.
Считывать до конца результирующий набор данных. При работе с набором данных, который описывает интерфейс IDatasetInstance, для считывания всех записей необходимо открыть кэш и получить значение свойства ICachedDataset.RecordCountAll. Обращение к данному свойству приведет к считыванию всех записей.
Также стоит учитывать рекомендации по разработке приложений, функционирующих в режиме MARS. Данные рекомендации представлены в MSDN.
См. также: