SQL-запросы с параметрами


Содержание лекционного занятия:

  •    Параметры при задании SQL-запроса
  •  Организация связи между таблицами
  •  Созданние связи между таблицами «один ко многим»

При задании SQL-запроса можно использовать параметры — переменные, вклю­чаемые в SQL-оператор, значения которых определяются во время выполнения программы. Параметры в значительной степени повышают гибкость SQL-запро­сов, обеспечивая возможность при выборке данных запрашивать у пользователя численные значения критериев выборки.

Параметры задаются в тексте SQL-запроса. Для определения параметра перед его именем указывается символ двоеточия (:), например:

SELECT *

FROM tablename

WHERE fieldl<:PARAM1

В данном запросе задан один параметр с именем PARAM1.

После ввода текста запроса в свойство SQL автоматически производится заполне­ние массива в свойстве Params. Одновременно значение свойства Params.Count ус­танавливается равным количеству заданных в запросе параметров. Последователь­ность заполнения массива Params соответствует порядку следования параметров в тексте запроса.

Свойства определенных в SQL-запросе параметров доступны для редактирования как во время разработки, так и во время выполнения программы.

  • Для редактирования свойств параметров во время разработки программы ис­пользуется специальный редактор, который вызывается щелчком на кнопке с многоточием в поле ввода свойства Params инспектора объектов.
  • Для задания значения параметра во время разработки программы вначале не­обходимо определить его тип с помощью свойства DataType класса TParam.
  • Для доступа к свойствам параметров SQL-запроса во время выполнения про­граммы можно воспользоваться либо свойством Items класса TParams, либо ме­тодом ParamByName этого же класса. Свойство Items предоставляет доступ к объектам параметров по их порядковым номерам, что не очень удобно. Обычно гораздо проще обращаться к параметрам по их именам с помощью метода ParamByName, возвращающего объект параметра, имя которого задается в каче­стве аргумента при вызове данного метода.
  • В зависимости от значения свойства ParamCheck при изменении текста запроса во время выполнения программы список параметров в свойстве Param может либо автоматически обновляться (ParamCheck = true), либо оставаться прежним  (ParamCheck = false).

Для практической иллюстрации концепции параметров модифицируем програм­му, которую мы использовали ранее при изучении SQL. С этой целью добавим на форму два компонента TEdit, которым присвоим имена edtParaml и edtParam2. Эти компоненты обеспечивают возможность изменения значений параметров во вре­мя выполнения программы. Изменим код метода-обработчика события OnClick кнопки Выполнить запрос, как показано в листинге 3.

Листинг 3. Обработчик события OnClick кнопки

procedure TfrmMain.btnExecQueryClick(Sender: TObject);

begin

if Queryl.Active then Queryl.Close;

Queryl.SQL.Clear;

Queryl.SQL.Ass i gn(memSQL. Li nes);

if Queryl.Params.Count>0

then begin

Queryl. Paranos. ParamByName('P_P1').Value:= StrToInt(edtParaml.Text);       

Queryl.Params.ParamByNameC'P_P2').Value:= StrToInt(edtParam2.Text);

 End;

Queryl.Open; end;

Теперь, если в запросе имеются параметры, их значения будут считываться из по­лей ввода edtParaml и edtParam2.

После запуска программы зададим следующий запрос, в котором определены два параметра (Р_Р1 и Р_Р2):

SELECT *

FROM Товары

WHERE (Цена>:Р_Р1) AND (Цена<:Р_Р2)

 

Рис. 38. Результат выполнения запроса с параметрами.

Зададим значения параметров с полей edtParaml и edtParam2 — в первом ука­жем значение 200 (значение первого параметра), во втором — 2000 (значение второго параметра). Если теперь щелкнуть на кнопке Выполнить запрос, то ре­зультатом будет вывод списка товаров, цена которых больше 200 и меньше 2000 (рис. 38).

Значения параметров могут передаваться из другого набора данных. Для этого в свойстве DataSource задается имя источника данных, связанного с набором дан­ных, значения полей которого передаются в параметры. Имена параметров в этом случае должны совпадать с именами полей набора данных, заданного в свойстве DataSource. При перемещении по исходному набору данных текущие значения по­лей автоматически передаются в запрос. Данный механизм позволяет организо­вать связь между таблицами базы данных, обращение к которым производится через SQL-запросы.

Рассмотрим простой пример организации связи между таблицами. Напишем про­грамму, в которой осуществляется связь между таблицами Товары и Продажи по общему для обеих таблиц полю Код товара. Таблица Товары будет главной, Прода­жи — подчиненной.

  1.  Создайте новое приложение с помощью команды FileNewVCL Form Appli­cations.
  2.  Поместите на форму по два экземпляра компонентов TQuery, TDataSource и TDBGrid. Затем переименуйте шесть размещенных на форме компонентов следующим образом: Master, Detail, dsMaster, dsDetail, DBGMaster, DBGDetail.
  3.  Для каждого компонента доступа к данным (Master и Detail) установите связь с базой данных sales.
  4. Свяжите источник данных dsMaster с компонентом доступа к данным Master, а ис­точник данных dsDetail — с компонентом Detail.
  5.  Свяжите элементы отображения данных DBGMaster и DBGDetail с источниками данных dsMaster и dsDetail, соответственно.
  6.  Задайте в свойстве SQL компонента Master следующий запрос:
  7. SELECT * FROM Товары
  8.  Задайте в свойстве SQL компонента Detail запрос, приведенный ниже:

SELECT *

FROM Продажи

WHERE [Код товара]=:"Код товара"

ВНИМАНИЕ. Если в качестве параметра используется имя поля таблицы, содержащее пробелы, то его необходимо заключать в кавычки.

8.  Выберите на форме компонент Detai l и щелкните в инспекторе объектов на кноп­ке с многоточием в поле свойства Params. В открывшемся окне редактора пара­метров выберите единственный параметр Код товара и задайте ему тип Integer (свойство DataType в инспекторе объектов).

9. Задайте обработчики событий формы OnShow и OnCtose. В первом вызовите метод Open для обеих таблиц:

procedure TForml.FormShowCSender: TObject); begin

Master.Open;

Detail.Open: end:

Во втором обработчике вызовите для двух таблиц метод Close:

procedure TForml.FormClosetSender: TObject: var Action: TCloseAction): begin

Master.Close:

Detail.Close; end;

10. Откомпилируйте и запустите программу. В одной из двух таблиц в окне про­граммы будет выводиться вся информация из таблицы Товары, во второй — те записи из таблицы Продажи, для которых значение поля Код товара равно зна­чению одноименного поля выбранной записи в таблице Товары (рис. 39).

Рис. 39. Пример связывания таблиц с использованием SQL-запросов

Созданная связь между таблицами соответствует отношению «один ко многим»-Отношение «многие ко многим» создается точно так же. В этом случае подчинен­ная таблица аналогичным образом связывается с еще одной таблицей в качестве главной. Например, в нашем случае можно было бы связать таблицу Продажи с таб­лицей Клиенты по общему для них полю Код клиента.

Вопросы для самоконтроля:

  1. Как описать доступ до необходимой базы данных?
  2. С помощью какой функции описывается соединение с необходимым источником данных? Каковы ее параметры?

Рекомендуемая литература:

  1. Миловзоров В.К. Элементы информационных систем. – М.: Высшая школа,1989.
  2. Морозов В.К. Основы теории информационных систем. – М.: Высшая школа, 1994.