TQuery и Параметры
Delphi позволяет составить “гибкую” форму запроса, называемую параметризованным запросом. Такие запросы позволяют подставить значение переменной вместо отдельных слов в выражениях “where” или “insert”. Эта переменная может быть изменена практически в любое время. (Если используется локальный SQL, то можно сделать замену почти любого слова в утверждении SQL, но при этом та же самая возможность не поддерживается большинством серверов.)
Перед тем, как начать использовать параметризованные запросы, рассмотрим снова одно из простых вышеупомянутых предложений SQL:
Select * from Country where Name like ’C%’
Можно превратить это утверждение в параметризованный запрос заменив правую часть переменной NameStr:
select * from County where Name like :NameStr
В этом предложении SQL, NameStr не является предопределенной константой и может изменяться либо во время дизайна, либо во время выполнения. SQL parser (программа, которая разбирает текст запроса) понимает, что он имеет дело с параметром, а не константой потому, что параметру предшествует двоеточие ":NameStr". Это двоеточие сообщает Delphi о необходимости заменить переменную NameStr некоторой величиной, которая будет известна позже.
Обратите внимание, слово NameStr было выбрано абсолютно случайно. Использовать можно любое допустимое имя переменной, точно также, как выбирается идентификатор переменной в программе.
Есть два пути присвоить значение переменной в параметризованном запросе SQL. Один способ состоит в том, чтобы использовать свойство Params объекта TQuery. Второй - использовать свойство DataSource для получения информации из другого DataSet. Вот ключевые свойства для достижения этих целей:
property Params[Index: Word];
function ParamByName(const Value: string);
property DataSource;
Если подставлять значение параметра в параметризованный запрос через свойство Params, то обычно нужно сделать четыре шага:
Закрыть TQuery
Подготовить объект TQuery, вызвав метод Prepare
Присвоить необходимые значения свойству Params
Открыть TQuery
Второй шаг выполняется в том случае, если данный текст запроса выполняется впервые, в дальнейшем его можно опустить.
Вот фрагмент кода, показывающий как это может быть выполнено практически:
Query1.Close;
Query1.Prepare;
Query1.Params[0].AsString := ‘Argentina’;
Query1.Open;
Этот код может показаться немного таинственным. Чтобы понять его, требуется внимательный построчный анализ. Проще всего начать с третьей строки, так как свойство Params является “сердцем” этого процесса.
Params - это индексированное свойство, которое имеет синтаксис как у свойства Fields для TDataSet. Например, можно получить доступ к первой переменной в SQL запросе, адресуя нулевой элемент в массиве Params:
Params[0].AsString := ‘”Argentina”’;
Если параметризованный SQL запрос выглядит так:
select * from Country where Name = :NameStr
то конечный результат (т.е. то, что выполнится на самом деле) - это следующее предложение SQL:
select * from Country where Name = “Argentina”
Все, что произошло, это переменной :NameStr было присвоено значение "Аргентина" через свойство Params. Таким образом, Вы закончили построение простого утверждения SQL.
Если в запросе содержится более одного параметра, то доступаться к ним можно изменяя индекс у свойства Params
Params[1].AsString := ‘SomeValue’;
либо используя доступ по имени параметра
ParamByName(‘NameStr’).AsString:=’”Argentina”’;
Итак, параметризованные SQL запросы используют переменные, которые всегда начинаются с двоеточия, определяя места, куда будут переданы значения параметров.
Прежде, чем использовать переменную Params, сначала можно вызвать Prepare. Этот вызов заставляет Delphi разобрать ваш SQL запрос и подготовить свойство Params так, чтобы оно "было готово принять” соответствующее количество переменных. Можно присвоить значение переменной Params без предварительного вызова Prepare, но это будет работать несколько медленнее.
П
осле
того, как Вы вызывали Prepare, и после того,
как присвоили необходимые значения
переменной Params, Вы должны вызвать Open,
чтобы закончить привязку переменных и
получить желаемый DataSet. В нашем случае,
DataSet должен включать записи где в поле
“Name” стоит “Argentina”.
Рассмотрим работу с параметрами на примере (программа PARAMS.DPR). Для создания программы, разместите на форме компоненты TQuery, TDataSource, TDBGrid и TTabSet. Соедините компоненты и установите в свойстве TQuery.DatabaseName псевдоним DBDEMOS. См. рис.2
Рис.2 : Программа PARAMS во время дизайна.
В обработчике события для формы OnCreate напишем код, заполняющий закладки для TTabSet, кроме того, здесь подготавливается запрос:
procedure TForm1.FormCreate(Sender: TObject);
var
i : Byte;
begin
Query1.Prepare;
for i:=0 to 25 do
TabSet1.Tabs.Add(Chr(Byte('A')+i));
end;
Текст SQL запроса в компоненте Query1:
select * from employee where LastName like :LastNameStr
Запрос выбирает записи из таблицы EMPLOYEE, в которых поле LastName похоже (like) на значение параметра :LastNameStr. Параметр будет передаваться в момент переключения закладок:
procedure TForm1.TabSet1Change(Sender: TObject;
NewTab:
Integer;
var AllowChange: Boolean);
begin
with Query1 do begin
Close;
Params[0].AsString:=
'"'+TabSet1.Tabs.Strings[NewTab]+'%"';
Open;
end;
end;
Рис.3: Программа PARAMS во время выполнения.
