Чтение онлайн

ЖАНРЫ

Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ

Борри Хелен

Шрифт:

SELECT <список выходных столбцов>

FROM имя-процедуры [ (<список входных значений>) ]

[WHERE <предикаты поиска>]

[ORDER BY <список выходных столбцов>]

В следующем фрагменте PSQL хранимая процедура принимает один ключ в качестве входного параметра и возвращает множество строк. Предложение RETURNS определяет выходной набор:

CREATE PROCEDURE GET_COFFEE_TABLE (IKEY INTEGER)

RETURNS (

BRAND_ID INTEGER,

VARIETY_NAME VARCHAR(40),

COUNTRY_OF_ORIGIN VARCHAR(30))

AS . . . . . .

Приложение

получает выходной набор из хранимой процедуры следующим образом:

SELECT BRAND_ID, VARIETY_NAME, COUNTRY_OF_ORIGIN FROM GET_COFFEE_TABLE (5002) ;

Тот же самый пример с параметризованным входным аргументом:

SELECT BRAND_ID, VARIETY_NAME, COUNTRY_OF_ORIGIN FROM GET_COFFEE_TABLE(:IKEY);/* Delphi */

или

SELECT BRAND_ID, , VARIETY_NAME, COUNTRY_OF_ORIGIN FROM GET_COFFEE_TABLE(?);

Использование параметров

"Непараметризованный" запрос использует константы в выражениях для условий поиска. Например, в запросе

SELECT MAX(COST * QUANTITY)

AS BEST_SALE FROM SALES

WHERE SALESEDATE > '31.12.2003' ;

будут обработаны те строки таблицы SALES, у которых дата в SALES_DATE более поздняя, чем последний день 2003 года.

Средства разработки доступа к данным, использующие API Firebird, имеют возможность обрабатывать константы в условиях поиска как заменяемые параметры. API позволяет передавать на сервер оператор в виде шаблона, представляющего эти параметры как заполнители, которые могут заменяться конкретными значениями. Клиент запрашивает подготовку (prepare) оператора - проверка синтаксиса и метаданных - без фактического его выполнения.

Приложение DSQL может создать оператор с динамическими условиями поиска в предложении WHERE, один раз подготовить его, а затем присваивать параметрам значения один или много раз непосредственно перед каждым выполнением. Такую возможность иногда называют динамическим связыванием. Средства разработки приложений отличаются по тем способам, которыми они реализуют динамическое связывание параметров во включающем языке. В зависимости от того, какое средство разработки вы используете, параметризованная версия последнего примера может выглядеть несколько иначе, например, так:

SELECT MAX (COST * QUANTITY) AS BEST_SALE

FROM SALES

WHERE SALES_DATE > ? ;

Заменяемый параметр в этом примере позволяет приложению подготовить оператор, а затем получать от пользователя (или от некоторой другой части приложения) фактическую дату, по которой запрос должен быть отфильтрован. Этот запрос может выполняться произвольное количество раз в одной и той же транзакции или в последовательности транзакций с различными значениями даты без необходимости повторной подготовки.

API "знает" порядок и формат параметров, потому что приложение передает описательные структуры XSQLDA, которые содержат массив SQLVAR- дескрипторы переменных, описывающих каждый параметр, - и другие данные, описывающие массив в целом.

Delphi и другие объектно-ориентированные реализации API используют методы и свойства классов, чтобы скрыть от разработчика механизм, применяемый для создания и управления

сырым оператором и дескрипторами. Другие средства разработки кодируют эти структуры иным образом. Оператор может передаваться на сервер приблизительно в таком виде:

INSERT INTO DATATABLE (DATAl, DATA2, DATA3, DATA4, DATA5,... другие столбцы)

VALUES (?, '?', '?', ?, ?, ... другие значения);

Если параметры реализованы в языке программирования вашего приложения, то весьма рекомендуется их использовать.

Замечания для пользователей Delphi

Delphi, имеющее клеймо "made in Borland", как и InterBase, предшественник Firebird, при передаче переменных включающего языка реализует формат, который повторяет формат, используемый в PSQL для ссылки на локальные переменные в SQL- операторах и ESQL. Он требует, чтобы все параметры были явно именованы и начинались с символа двоеточия. В Delphi предыдущий простой пример может быть представлен в свойстве SQL объекта доступа к данным в следующем виде:

SELECT MAX(COST * QUANTITY) AS BEST_SALE

FROM SALES

WHERE SALES_DATE > :SALES_DATE ;

Один вызов метода PREPARE приведет к проверке оператора и передаче описания метаданных назад в клиентское приложение; объект доступа к данным позволяет позже присваивать значение параметру, используя локальный метод, который выполняет преобразование значения к формату, требуемому в Firebird:

aQuery.ParamByName ('SALES_DATE').AsDate := ALocalDateVariable;

Пакетные операции

Очень часто требуется выполнение задач, которые добавляют, изменяют или удаляют множество строк в одной операции. Например, приложение читает файл данных с внешнего устройства и помещает данные в операторы INSERT для помещения в таблицу базы данных. или сервис репликации обрабатывает пакеты изменений между вспомогательной и родительской базами данных. Множество похожих операторов выполняется в одной транзакции обычно с помощью подготовленного оператора и заменяемых во время выполнения параметров.

Пакетные добавления

Оператор для пакетных добавлений может выглядеть следующим образом:

INSERT INTO DATATABLE(DATA1, DATA2, DATA3, DATA4, DATA5, . . . другие столбцы)

VALUES ('x', 'у', 'z', 99, '2004-12-25', . . . другие значения);

При использовании параметров он будет выглядеть так:

INSERT INTO DATATABLE(DATA1, DATA2, DATA3, DATA4, DATA5, . . . другие столбцы)

VALUES (?, '?', '?', ?, ?, .... другие значения);

Часто хранимая процедура бывает наиболее элегантным способом выполнения повторяемой пакетной операции, особенно если есть требование преобразования данных по дороге к таблице базы данных или при добавлении строк во множество таблиц.

Предотвращение замедления пакетной операции

Два поведения могут привести к огромному объему пакетных операций, резко замедляющих выполнение.

* Использование индексов, которые добавляют задаче работы, а также имеют тенденцию к деформированию геометрии индексных деревьев.

Поделиться с друзьями: