Управляющие структуры PL / pgSQL: if-else, case, loop
Вступление
В этом разделе мы опишем все операторы структур управления, структуры управления, вероятно, являются наиболее полезной частью PL / pgSQL. С управляющими структурами PL / pgSQL вы можете управлять данными PostgreSQL очень гибким и мощным способом.
Условные заявления
IF и CASE являются двумя условными утверждениями, и они используются при определенных условиях. Вот синтаксис операторов IF (три формы):
ЕСЛИ ... ТОГДА
Синтаксис:
ЕСЛИ ... ТО ... ЕЩЕ
Синтаксис:
ЕСЛИ ... ТО ... ЭЛСИФ ... ТО ... ЕЩЕ
Две формы синтаксиса CASE:
Синтаксис:
СЛУЧАЙ ... КОГДА ... ТО ... ЛИБО ... КОНЕЦ СЛУЧАЯ
Синтаксис:
СЛУЧАЙ КОГДА ... ТОГДА ... ДРУГОЙ ... КОНЕЦ
IF-THEN
Синтаксис:
ЕСЛИ логическое выражение ТОГДА заявления END IF;
IF-THEN заявления являются простейшей формой IF. Операторы между THEN и END IF будут выполнены, если условие выполнено. В противном случае они пропускаются.
Примеры:
Код:
CREATE OR REPLACE FUNCTION ifstat()
RETURNS text AS $$
DECLARE
ss integer;
BEGIN
ss:= 0;
IF ss = 0 THEN
RETURN 'You have declared zero';
END IF;
END;
Пример вывода:
postgres = # select ifstat (); ifstat ------------------------ Вы объявили ноль (1 ряд)
IF-THEN-ELSE
Код:
CREATE OR REPLACE FUNCTION ifstat (date)
RETURNS text
AS
$$
BEGIN
IF EXTRACT(DAY FROM current_date) = 1
THEN
RETURN '1st day of the Month';
ELSE
RETURN 'Other day';
END IF;
END;
$$
LANGUAGE plpgsql;
Чтобы увидеть результат от функции
postgres = # SELECT _ifstat1 (current_date); ifstat ----------- Другой день (1 ряд)
Операторы IF-THEN-ELSE добавляют к IF-THEN, позволяя вам указать альтернативный набор операторов, которые должны выполняться, если условие не выполняется. (Обратите внимание, что это включает случай, когда условие оценивается как NULL.)
Вот пример таблицы сотрудников
empno | emp_first_name | emp_last_name | дизайн | dt_birth | mngr_no | dt_join | зарплата | комиссия | вычет | DEPTNO ------- + ----------------- + ----------------- + ------ ----------- + ------------ + --------- + ------------ + - -------- + ------------ + ----------- + -------- 8328 | ДАМАС | FORK | ПРОДАВЕЦ | 1983-10-12 | 8743 | 2006-06-14 | 7000,00 | 1500,00 | 600,00 | 25 8450 | Гарри | DIGGA | МЕНЕДЖЕР | 1975-09-05 | 8640 | 1999-09-15 | 20000,00 | | 1200,00 | 15 8425 | JONE | KALE | CLERCK | 1983-08-06 | 8653 | 2004-02-03 | 11000,00 | | 700,00 | 45 8640 | ЗОЛЕ | НЕЛЬСОН | ПРЕЗИДЕНТ | 1970-08-03 | | 1996-03-28 | 35000,00 | | 1200,00 | 15 8639 | ДЖЕЙМС | ПЕТРО | ПРОДАВЕЦ | 1985-04-15 | 8653 | 2007-11-13 | 9000,00 | 1700,00 | 650,00 | 15 8744 | DAWIZ | ДОНАЛЬД | CLERCK | 1980-03-13 | 8743 | 2002-05-12 | 10000,00 | | 700,00 | 35 8752 | ФАРИН | ДЖЕЙОС | МЕНЕДЖЕР | 1972-10-12 | 8640 | 1997-07-14 | 22500,00 | | 900,00 | 25 8743 | Скотт | NATIM | ОФИЦЕР | 1975-03-14 | 8861 | 2000-05-23 | 26000,00 | | 1400,00 | 15 8892 | УОЛКОТ | ХИЛЛ | ПРОДАВЕЦ | 1982-11-15 | 8653 | 2001-12-16 | 8000,00 | 1200,00 | 650,00 | 25 8861 | ТУРПЕО | СОБАКИ | МЕНЕДЖЕР | 1975-07-06 | 8640 | 1998-09-17 | 21000,00 | | 1000,00 | 25 8875 | CAMLI | ПАЛИН | CLERCK | 1973-12-17 | 8653 | 1999-06-18 | 11000,00 | | 600,00 | 45 8869 | FASCO | СВАРИТЬ | АНАЛИТИКА | 1981-02-18 | 8752 | 2002-12-24 | 18000,00 | | 800,00 | 15 8950 | CADRIM | Катен | CLERCK | 1976-10-17 | 8653 | 2003-06-16 | 11500,00 | | 500,00 | 25 8653 | Дэнон | FORGE | ОФИЦЕР | 1971-07-02 | 8752 | 1994-10-17 | 25000,00 | | 1000,00 | 35 (14 рядов)
Пример:
Код:
CREATE OR REPLACE FUNCTION no_emp(integer,integer) RETURNS integer AS '
DECLARE
emp_id ALIAS FOR $1;
tot_dept ALIAS FOR $2;
tmp_id integer;
no_emp integer;
BEGIN
SELECT INTO tmp_id mngr_no FROM employee WHERE
empno = emp_id;
IF tmp_id IS NULL THEN
RETURN -1;
END IF;
SELECT INTO no_emp count(*) FROM employee WHERE deptno=tot_dept;
RETURN no_emp;
END;
' LANGUAGE 'plpgsql';
Пример вывода:
postgres = # SELECT no_emp (8640,15) от сотрудника; no_emp -------- -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 (14 рядов)
IF-THEN-ELSEIF :
Синтаксис:
ЕСЛИ логическое выражение ТОГДА заявления [ELSIF логическое выражение THEN заявления [ELSIF логическое выражение THEN заявления ...]] [Иначе заявления ] END IF;
Операторы IF-THEN-ELSE добавляют к IF-THEN, позволяя вам указать альтернативный набор операторов, которые должны выполняться, если условие не выполняется. (Обратите внимание, что это включает случай, когда условие оценивается как NULL.)
Пример:
Код:
CREATE FUNCTION ret_date (crdate date) RETURNS text AS $$
BEGIN
IF EXTRACT (MONTH FROM crdate)= 1
THEN RETURN 'January';
ELSIF EXTRACT (MONTH FROM crdate)= 2
THEN RETURN 'February';
ELSIF EXTRACT (MONTH FROM crdate)= 3
THEN RETURN 'March';
ELSIF EXTRACT (MONTH FROM crdate)= 4
THEN RETURN 'April';
ELSIF EXTRACT (MONTH FROM crdate)= 5
THEN RETURN 'May';
ELSIF EXTRACT (MONTH FROM crdate)= 6
THEN RETURN 'June';
ELSIF EXTRACT (MONTH FROM crdate)= 7
THEN RETURN 'July';
ELSIF EXTRACT (MONTH FROM crdate)= 8
THEN RETURN 'August';
ELSIF EXTRACT (MONTH FROM crdate)= 9
THEN RETURN 'September';
ELSIF EXTRACT (MONTH FROM crdate)= 10
THEN RETURN 'October';
ELSIF EXTRACT (MONTH FROM crdate)= 11
THEN RETURN 'November';
ELSIF EXTRACT (MONTH FROM crdate)= 12
THEN RETURN 'December';
END IF;
END;
$$
LANGUAGE plpgsql
Пример вывода:
postgres = # SELECT ret_date (CURRENT_DATE); ret_date ----------- сентябрь (1 ряд) postgres = # select ret_date ('2014-05-05'); ret_date ---------- май (1 ряд)
Простой случай
Синтаксис:
CASE поиск-выражение КОГДА выражение [, выражение [...]] THEN заявления [КОГДА выражение [, выражение [...]] ТОГДА заявления ...] [Иначе заявления ] КОНЕЦ ДЕЛА;
Простая форма CASE обеспечивает условное выполнение, основанное на равенстве операндов. Поисковое выражение оценивается (один раз) и последовательно сравнивается с каждым выражением в предложениях WHEN. Если совпадение найдено, то соответствующие операторы выполняются, а затем управление переходит к следующему оператору после END CASE. (Последующие выражения WHEN не оцениваются.) Если совпадений не найдено, выполняются операторы ELSE; но если ELSE нет, то возникает исключение CASE_NOT_FOUND.
Примеры:
Код:
SELECT salary,
CASE WHEN department_id =90 THEN 'High Salary'
WHEN department_id =100 THEN '2nd grade salary'
ELSE 'Low Salary'
END
AS salary_status
FROM employees
LIMIT 15;
Пример вывода:
зарплата | salary_status ---------- + ------------------ 24000,00 | Высокая зарплата 17000,00 | Высокая зарплата 17000,00 | Высокая зарплата 9000,00 | Низкая зарплата 6000,00 | Низкая зарплата 4800,00 | Низкая зарплата 4800,00 | Низкая зарплата 4200,00 | Низкая зарплата 12000,00 | Зарплата 2 класса 9000,00 | Зарплата 2 класса 8200,00 | Зарплата 2 класса 7700,00 | Зарплата 2 класса 7800,00 | Зарплата 2 класса 6900,00 | Зарплата 2 класса 11000,00 | Низкая зарплата (15 рядов)
Искал дело
Синтаксис:
ДЕЛО КОГДА булево выражение ТОГДА заявления [КОГДА БУЛЕВОЕ ВЫРАЖЕНИЕ ТОГДА заявления ...] [Иначе заявления ] КОНЕЦ ДЕЛА;
Найденная форма CASE обеспечивает условное выполнение, основанное на истинности логических выражений. Булево-выражение каждого предложения WHEN вычисляется по очереди, пока не будет найдено одно, которое выдает true. Затем выполняются соответствующие операторы, а затем управление переходит к следующему оператору после END CASE. (Последующие выражения WHEN не оцениваются.) Если истинный результат не найден, выполняются операторы ELSE; но если ELSE нет, то возникает исключение CASE_NOT_FOUND.
Примеры:
Код:
CREATE OR REPLACE FUNCTION myfunc1 (x integer) RETURNS text AS $$
DECLARE
msg text;
BEGIN
CASE
WHEN x IN(2,4,6,8,10) THEN
msg :='value even number';
WHEN x IN(3,5,7,9,11) THEN
msg :='value is odd number';
END CASE;
RETURN msg;
END;
$$
LANGUAGE plpgsql
Вот выполнение вышеуказанной функции.
Пример вывода:
postgres = # SELECT myfunc1 (5); myfunc1 --------------------- значение нечетное число (1 ряд)
Loops
Циклы также могут вызывать условные операторы, которые могут управлять потоком функций. Циклы используются для повторения ряда различных способов достижения задач, и с помощью повторения вы можете значительно расширить функциональность функции PL / pgSQL. PL / pgSQL реализует три итерационных цикла: базовый цикл, довольно продвинутый цикл WHILE и цикл FOR.
С помощью операторов LOOP, EXIT, CONTINUE, WHILE, FOR и FOREACH вы можете настроить функцию PL / pgSQL на повторение ряда команд.
Основной цикл
Ключевое слово LOOP используется для запуска базового безусловного цикла внутри функции. Основная задача безусловного цикла - выполнять операторы внутри его тела, пока он не достигнет оператора EXIT. Чтобы достичь оператора EXIT, требуется ключевое слово EXIT вместе с WHEN, за которым следует и выражение, которое содержит условие для достижения EXIT из цикла.
Вот синтаксис (без ключевого слова ELSE) для безусловного цикла:
Синтаксис:
<LOOP заявление; [...] КОНЕЦ ЦИКЛА;
Оператор безусловного цикла будет повторяться до тех пор, пока не достигнет оператора EXIT. Когда цикл завершается с помощью EXIT, вы можете при желании указать метку и, необязательно, условие, из которого цикл должен выйти.
Вот синтаксис: определенного цикла с меткой:
[<< ярлык >>] LOOP [...] КОНЕЦ ЦИКЛА;
Метка может помочь вам указать, какой цикл следует завершить, когда у вас есть больше, чем циклы, вложенные друг в друга, и условие решает, когда цикл должен быть завершен, в зависимости от того, вернул ли он значение true или false.
Вот синтаксис оператора EXIT в цикле LOOP:
Синтаксис:
[<< ярлык >>] LOOP заявление; [...] ВЫХОД [метка] [КОГДА условие]; КОНЕЦ ЦИКЛА;
Примеры:
Код:
CREATE OR REPLACE FUNCTION myfunction(integer)
RETURNS integer AS '
DECLARE
nm ALIAS FOR $1;
cub integer;
BEGIN
cub := nm;
LOOP
cub := cub * cub * cub;
EXIT WHEN cub >= 10000;
END LOOP;
RETURN cub;
END;
' LANGUAGE 'plpgsql';
Вот выполнение вышеуказанной функции.
Пример вывода:
postgres = # ВЫБРАТЬ myfunction (5); MyFunction ------------ 1953125 (1 ряд)
WHILE петля
Цикл WHILE используется для многократного выполнения работы в блоке операторов до тех пор, пока указанное условие не станет ложным. В цикле этого типа упомянутое условие будет выполнено в первую очередь перед выполнением блока операторов.
Вот синтаксис цикла WHILE:
Синтаксис:
[<< ярлык >>] Пока состояние петли заявление; [...] КОНЕЦ ЦИКЛА;
Примеры:
Код:
CREATE OR REPLACE FUNCTION myfunction(integer)
RETURNS integer AS '
DECLARE
nm ALIAS FOR $1;
cub INTEGER;
BEGIN
cub:=nm;
WHILE cub <=10000 LOOP
cub := cub * cub * cub;
END LOOP;
RETURN cub;
END;
' LANGUAGE 'plpgsql';
Вот выполнение вышеуказанной функции.
Пример вывода:
postgres = # ВЫБРАТЬ myfunction (5); MyFunction ------------ 1953125 (1 ряд)
Цикл FOR
Используйте цикл FOR, чтобы повторить определенный оператор (ы) в блоке в диапазоне указанных терминов.
В цикле PL / pgSQL FOR необходимо инициализировать целочисленную переменную, отследить повторение цикла, затем дать конечное целочисленное значение и, наконец, в цикле предоставляется блок операторов.
Вот синтаксис цикла FOR:
Синтаксис:
[<< ярлык >>] Идентификатор FOR в [REVERSE] выражение1 .. выражение2 LOOP заявление; [...] КОНЕЦ ЦИКЛА;
Параметры :
название | Описание |
идентификатор | Идентификатор используется для отслеживания повторения задания оператора (ей). Это значение будет увеличено на единицу, если REVERSE не указано, в противном случае оно будет уменьшено. |
expression1, expression2 | Начальное и конечное значение идентификатора |
Пример:
Код:
CREATE OR REPLACE FUNCTION myfunction(integer)
RETURNS integer AS '
DECLARE
nm ALIAS FOR $1;
cub INTEGER;
BEGIN
cub :=nm;
FOR i IN 0..10000 LOOP
cub := cub * cub * cub;
END LOOP;
RETURN cub;
END;
' LANGUAGE 'plpgsql';
Вот выполнение вышеуказанной функции.
Пример вывода:
postgres = # ВЫБРАТЬ myfunction (5); MyFunction ------------ 1953125 (1 ряд)
Вот еще один пример:
Код:
CREATE OR REPLACE FUNCTION myfunction(dt DATE)
RETURNS INTEGER
AS
$$
DECLARE ddt DATE;
num INTEGER;
x INTEGER;
BEGIN
ddT := dt;
x := EXTRACT(MONTH FROM dt);
FOR i IN 1 .. 31
LOOP
num := i;
EXIT WHEN EXTRACT(MONTH FROM ddt + i * INTERVAL '1 DAY') <> x;
END LOOP;
RETURN num-1;
END;
$$
LANGUAGE PLPGSQL
Вот выполнение функции
Пример вывода:
postgres = # SELECT myfunction (current_date); MyFunction ------------ 17 (1 ряд)
Цикл FOR также можно использовать для циркуляции результатов запроса. Цикл FOR также работает с переменными RECORD и% ROWTYPE.
Вот синтаксис цикла FOR, который повторяется через переменные RECORD и% ROWTYPE.
Синтаксис:
[<< ярлык >>] FOR {record_variable | % rowtype_variable} IN select_statement LOOP заявление; [...] КОНЕЦ ЦИКЛА;
Примеры:
Код:
CREATE OR REPLACE FUNCTION myfunction(integer) RETURNS text AS '
DECLARE
depid ALIAS FOR $1;
output_txt TEXT :=''\n'';
row_data employees%ROWTYPE;
BEGIN
FOR row_data IN SELECT * FROM employees
WHERE department_id = depid ORDER BY first_name LOOP
output_txt := output_txt || row_data.first_name || row_data.last_name || ''\n'';
END LOOP;
RETURN output_txt;
END;
' LANGUAGE 'plpgsql';
Вот выполнение вышеуказанной функции.
Пример вывода:
postgres = # ВЫБРАТЬ myfunction (90); MyFunction ------------------------------------------ / nLexDe Haan / nNeenaKochhar / nStevenKing / n (1 ряд)
Предыдущая: Основные положения
Далее: Последовательность PostgreSQL
Новый контент: Composer: менеджер зависимостей для PHP , R программирования