Навеяно статьей Евгения Степанищева и его статьей о 99 бутылок пива.
https://bolknote.ru/tags/beer99/
Но реализация циклов показалась слишком «заковыристой» для практического применения.
Решил попробовать для этих целей команду \watch входящую в psql
Из документации psql, команда \watch:
\watch [СЕК] повторяет запрос в цикле через заданное число секунд
Но при этом, если возникает ошибка при очередном выполнении запроса, \watch завершает работу. Мы можем использовать это свойство для выхода из цикла котором выполняется \watch.
Создадим функцию, которая генерирует целые случайные числа в интервале от 0 до 100. Но при этом если получившееся число больше 80 – функция вызывает ошибку:
CREATE OR REPLACE FUNCTION test_loop() RETURNS integer AS $$
DECLARE
r1 int;
BEGIN
SELECT (random()*100)::integer INTO r1;
RAISE NOTICE 'Current value: %', r1;
IF r1 > 80 THEN
RAISE EXCEPTION 'R > 80. Exiting watch.';
END IF;
RETURN r1;
END
$$ LANGUAGE plpgsql;
Заходим в psql
#psql -U postgres -h 127.0.0.1 test
Выполняем вызов нашей функции test_loop() , за которой \watch [интервал в секундах]
Замечу, что интервал может быть и меньше секунды, например 0.1 сек.
test=# SELECT test_loop(); \watch 1
NOTICE: Current value: 50
test_loop
-----------
50
(1 строка)
NOTICE: Current value: 36
Чт 29 окт 2020 13:07:23 (обновление: 1 с)
test_loop
-----------
36
(1 строка)
NOTICE: Current value: 98
ERROR: R > 80. Exiting watch.
КОНТЕКСТ: PL/pgSQL function test_loop() line 8 at RAISE
Мы видим, что \watch прекратил свою работу при значении 98, которое больше 80 по нашему условию в функции.