Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
Более подробную информацию о явном преобразовании и о конвертировании типов данных см. в главах 8 и 21.
Локальные переменные объявляются, каждая в отдельной строке, до первого оператора BEGIN. Они не имеют значения вне хранимой процедуры или триггера, их область действия не распространяется на другие вызываемые процедуры. Они должны быть объявлены до их использования.
Вам следует всегда инициализировать ваши переменные насколько возможно раньше в вашей процедуре. В Firebird 1.5 вы можете объявлять и инициализировать
. . .
DECLARE VARIABLE COUNTER1 INTEGER DEFAULT 0;
DECLARE VARIABLE COUNTER2 INTEGER = 0;
Следующая процедура иллюстрирует фрагмент австралийской шутки о правильности пословицы: "Никогда не ешь свинину, если в названии месяца есть буква R". Она возвращает мнение по поводу полученной даты. Для иллюстрации в ней объявляется одна локальная переменная, которая используется для получения стартового условия для цикла WHILE, и другая - для управления количеством повторов цикла.
CREATE PROCEDURE IS_PORK_SAFE (CHECK_MONTH DATE)
RETURNS (RESPONSE CHAR(3))
AS
DECLARE VARIABLE SMONTH VARCHAR(9);
DECLARE VARIABLE SI SMALLINT;
BEGIN
SI = 0;
RESPONSE = ' NO'
SELECT
CASE (EXTRACT (MONTH FROM :CHECK MONTH) )
WHEN 1 THEN 'JANUARY'
WHEN 2 THEN ' FEBRUARY'
WHEN 3 THEN 'MARCH'
WHEN 4 THEN 'APRIL'
WHEN 5 THEN 'MAY'
WHEN 6 THEN 'JUNE'
WHEN 7 THEN ' JULY'
WHEN 8 THEN 'AUGUST'
WHEN 9 THEN 'SEPTEMBER'
WHEN 10 THEN 'OCTOBER'
WHEN 11 THEN 'NOVEMBER'
WHEN 12 THEN 'DECEMBER'
END
FROM RDB$DATABASE
INTO :SMONTH;
WHILE (SI < 9) DO
BEGIN
SI = SI + 1;
IF (SUBSTRING(SMONTH FROM 1 FOR 1) = 'R') THEN
BEGIN
RESPONSE = 'YES';
LEAVE;
END
SMONTH = SUBSTRING(SMONTH FROM 2);
END
END ^
COMMIT ^
SET TERM;^
Можно ли автору есть свинину в ее день рождения?
EXECUTE PROCEDURE IS_PORK_SAFE ('2004-05-16');
RESPONSE
=========
NO
! ! !
СОВЕТ. Если бы это была серьезная процедура, в SQL есть более быстрый способ получения того же результата. Например, вместо цикла WHILE вы можете просто проверить переменную SMONTH:
IF (SMONTH CONTAINING 'R') THEN RESPONSE = 'YES' ELSE RESPONSE = 'NO'
Вероятно, вы захотите использовать внешнюю функцию для получения названия месяца. В версии 1.5 вы можете инициализировать переменные при их объявлении.
. ! .
Входные аргументы (также называемые параметрами) используются для передачи значений от приложения процедуре или от одного модуля PSQL другому. Они объявляются списком в скобках следом за именем процедуры и отделяются друг от друга запятыми. Один раз объявленные,
Например, следующий фрагмент процедуры определяет один входной параметр, чтобы сообщить процедуре, какая страна должна отыскиваться:
CREATE PROCEDURE SHOW_JOBS_FOR_COUNTRY (
COUNTRY VARCHAR(15))
. . .
Входные параметры передаются от вызывающей программы хранимой процедуре по значению. Это означает, что если процедура изменит значение входного параметра, это изменение будет иметь эффект только в процедуре. Когда управление возвращается вызвавшей программе, входной параметр в любом случае будет иметь первоначальное значение.
Входные аргументы недопустимы в триггерах.
Выходной аргумент (параметр) используется для задания значения, возвращаемого из процедуры вызвавшему приложению или модулю PSQL. Если задается множество возвращаемых значений, объявляйте эти аргументы в скобках, отделяя их друг от друга запятыми, следом за ключевым словом RETURNS В заголовке процедуры. Один раз объявленные, они могут использоваться в теле процедуры везде, где могут появиться выражения.
Следующий код завершает определение процедуры, представленной предыдущим фрагментом. Он определяет три элемента данных для возвращения в виде виртуальной таблицы вызвавшему модулю:
CREATE PROCEDURE SHOW_JOBS_FOR_COUNTRY (
COUNTRY VARCHAR (15) )
RETURNS (
CODE VARCHAR (11) ,
TITLE VARCHAR (25) ,
GRADE SMALLINT)
AS
BEGIN
FOR SELECT JOB_CODE, JOB_TITLE, JOB_GRADE FROM job
WHERE JOB_COUNTRY = : COUNTRY
INTO :CODE, :TITLE, :GRADE
DO
BEGIN /* начало цикла */
CODE = 'CODE: ' || CODE;
/* дает немного информации о значении */
SUSPEND; /* выводит одну строку цикла */
END
END ^
Если вы объявляете выходные параметры в заголовке процедуры, процедура должна присвоить им значения, чтобы вернуть их вызвавшему приложению. Значения могут быть получены из любого допустимого выражения в процедуре.
! ! !
СОВЕТ. Всегда инициализируйте выходные параметры до начала обработки данных, которые могут быть присвоены параметрам.
. ! .
Триггеры могут использовать два полных набора контекстных переменных, представляющих "старое" и "новое" значение каждого столбца таблицы, OLD .имя-столбца ссылается на текущее или предыдущее значение именованного столбца в изменяемой или удаляемой строке. Это не имеет смысла для добавления данных, NEW.имя-столбца ссылается на значение, передаваемое запросом на изменение или добавление. Не имеет смысла для удаления. Если операция обновления не изменяет некоторые столбцы, то для таких столбцов переменная NEW будет иметь то же самое значение, что и переменная OLD. Контекстные переменные часто используются для сравнения значений столбцов до и после изменения.