Входные параметры передаются от вызывающей программы хранимой процедуре по значению. Это означает, что если процедура изменит значение входного параметра, это изменение будет иметь эффект только в процедуре. Когда управление возвращается вызвавшей программе, входной параметр в любом случае будет иметь первоначальное значение.
Входные аргументы недопустимы в триггерах.
Выходной аргумент (параметр) используется для задания значения, возвращаемого из процедуры вызвавшему приложению или модулю 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. Контекстные переменные часто используются для сравнения значений столбцов до и после изменения.
Контекстные переменные могут применяться везде, где могут быть использованы обычные переменные. Значение NEW для столбца строки может быть изменено только до соответствующего действия. Значения OLD являются значениями только для чтения. Подробности и примеры использования см. в главе 31.
! ! !
СОВЕТ. Поскольку Firebird создает триггеры для реализации ограничений CHECK, контекстные переменные OLD и NEW могут использоваться непосредственно в ограничениях CHECK, например:
ALTER TABLE EMPLOYEE
ADD CONSTRAINT EMPLOYEE_SALARY_RAISE_CK
CHECK ((OLD.SALARY IS NULL) OR (NEW.SALARY > OLD.SALARY));
. ! .
Операторы SELECT ... INTO
Используйте оператор SELECT С предложением INTO для поиска значений столбцов в таблицах и сохранения их в локальных переменных или выходных аргументах.
Обычный оператор SELECT В PSQL должен возвращать не более одной строки из базы данных- стандартный одиночный (singleton) оператор SELECT. ЕСЛИ оператор возвращает более одной строки, то будет выдано исключение. Предложение ORDER BY недопустимо в одиночном SELECT кроме случая, когда используется оператор SELECT FIRST 1. (Информацию об использовании квалификатора FIRST см. В znaee 21.)
Обычные правила применяются к входному списку, предложению WHERE и предложению GROUP BY, если оно используется. Предложение INTO требуется и должно быть последним предложением в операторе.
Пример одиночного оператора SELECT В параметризованном запросе DSQL в приложении:
SELECT SUM(BUDGET), AVG(BUDGET)
FROM DEPARTMENT
WHERE HEAD_DEPT = :head_dept;
Для использования этого оператора в процедуре объявите локальные переменные или выходные аргументы и добавьте предложение INTO в конец:
. . .
DECLARE VARIABLE TOT_BUDGET NUMERIC(18,2);
DECLARE VARIABLE AVG_BUDGET NUMERIC(18,2);
. . .
SELECT SUM(BUDGET), AVG(BUDGET)
FROM DEPARTMENT
WHERE HEAD_DEPT = :head_dept
INTO :tot_budget, :avg_budget;
Любой модуль PSQL может оперировать с множеством входных строк, полученных из оператора SELECT, когда он содержит структуру цикла, который может "перемещаться" по набору и выполнять одинаковую обработку каждой строки. PSQL не может обрабатывать многострочные наборы другим способом, и при отсутствии контекста цикла многострочная выборка данных вызовет исключение ("Multiple rows in singleton select" - "Множество строк в одиночном операторе SELECT").
Основным методом реализации структуры цикла для обработки многострочных входных наборов является структура FOR ... SELECT ... INTO ... DO. Его упрощенный синтаксис:
FOR SELECT <список-спецификации-набора>
FROM имя-таблицы
[JOIN..]