Использование операторов IF, CASE и LOOP
ОБЗОР. В этой статье рассматриваются управляющие структуры, которые можно использовать в хранимых процедурах PostgreSQL, с синтаксисом и примерами для каждой из них.
1. Операторы ЕСЛИ
a. Простые операторы ЕСЛИ
b. Операторы IF-THEN-ELSE
2. Операторы CASE
3. Операторы LOOP
Хранимые процедуры в PostgreSQL — это те, которые определяют функцию для создания триггеров или пользовательских функций. Существует три основных типа структур управления, доступных в PostgreSQL для использования с хранимыми процедурами: IF, CASE и LOOP.
операторы ЕСЛИ
1. Простые операторы ЕСЛИ
Синтаксис
ЕСЛИ условие ТО утверждение; КОНЕЦ ЕСЛИ;
Условие ЕСЛИ запускается, когда условие оценивается как истинное. Если условие ложно, то оно переходит к следующему оператору после END IF.
Пример
ДЕЛАТЬ $$ ЗАЯВИТЬ х целое := 10; у целое число := 20; НАЧИНАТЬ ЕСЛИ х > у, ТО RAISE NOTICE 'x больше, чем y'; КОНЕЦ ЕСЛИ; ЕСЛИ х < у, ТО RAISE NOTICE 'x меньше y'; КОНЕЦ ЕСЛИ; ЕСЛИ х = у, ТО RAISE NOTICE 'x равно y'; КОНЕЦ ЕСЛИ; КОНЕЦ $$;
В приведенном выше примере в начале объявляются 2 переменные. X и y были присвоены значения. То есть х=10 и у=20.
Далее следуют три условия: когда x больше y, x меньше y и x равно y. В зависимости от выполненного условия будет выведено уведомление — в данном случае «x меньше y».
2. Операторы IF-THEN-ELSE
Синтаксис
ЕСЛИ условие ТО заявления; ЕЩЕ дополнительные заявления; КОНЕЦ ЕСЛИ;
Пример
ДЕЛАТЬ $$ ЗАЯВИТЬ х целое := 10; у целое число := 20; НАЧИНАТЬ ЕСЛИ х > у, ТО RAISE NOTICE 'x больше, чем y'; ЕЩЕ RAISE NOTICE 'x не больше y'; КОНЕЦ ЕСЛИ; КОНЕЦ $$;
Как и в первом примере, здесь в начале объявлены 2 переменные: x=10 и y=20.
Далее, есть одно условие: когда x больше, чем y, возникает уведомление, что «x больше, чем y». Когда это условие не выполняется, выдается сообщение «x не больше, чем y». В этом случае условие не выполняется, поэтому выполняется предложение ELSE и печатается вывод для части ELSE.
Операторы CASE
Оператор CASE использует логику IF-THEN-ELSE в рамках одного оператора. Он упрощает условные запросы, выполняя работу оператора IF-THEN-ELSE и применяя его ко многим возможным условиям.
Синтаксис
СЛУЧАЙ Состояние КОГДА значение условия ТОГДА инструкция ELSE дополнительная инструкция;
Пример
Мы можем использовать CASE для оценки нескольких условий для одной переменной «job_id». Если «job_id» равен «ACCOUNT», повышение зарплаты составляет 10%; если «job_id» равен «IT_PROG», прибавка к зарплате составляет 15%; если «job_id» — «ПРОДАЖИ», повышение зарплаты составляет 20%. Для всех остальных должностей оклад не увеличивается.
ВЫБЕРИТЕ last_name, job_id, зарплата, ДЕЛО job_id КОГДА 'СЧЕТ' ТО 1.10*зарплата КОГДА 'IT_PROG' ТО 1.15*зарплата КОГДА ПРОДАЖА, ТО 1,20*зарплата ELSE зарплата END "REVISED_SALARY" ОТ сотрудников;
операторы LOOP
Синтаксис
ПЕТЛЯ <запуск блока выполнения> <Условие ВЫХОДА на основе требования>КОНЕЦ ПЕТЛИ;
Ключевое слово LOOP объявляет начало цикла, а END LOOP объявляет конец цикла. Блок выполнения содержит весь код, который необходимо выполнить, включая условие EXIT.
Пример
ДЕЛАТЬ $$ ЗАЯВИТЬ ЧИСЛО:=1; НАЧИНАТЬ RAISE NOTICE 'Цикл запущен.'; ПЕТЛЯ ПОДНЯТЬ УВЕДОМЛЕНИЕ 'a'; а:=а+1; ВЫХОД КОГДА a>5; КОНЕЦ ПЕТЛИ; RAISE NOTICE 'Цикл завершен'; КОНЕЦ; КОНЕЦ $$;
Застрял в цикле обновления после обновления PostgreSQL 13 — поддержка
Мета дискурса Алехандроф (Алекс Армстронг)#1
Я прочитал здесь документы, и они не охватывают мою ситуацию: Обновление PostgreSQL 13
Я застрял в ситуации «Каждая перестройка снова выполняет обновление, также известное как цикл обновления»:
------- -------------------------------------------------- ---------------------------- ОБНОВЛЕНИЕ POSTGRES ЗАВЕРШЕНО Старая база данных 10 хранится в /shared/postgres_data_old Чтобы завершить обновление, выполните повторную сборку, используя: . /лаунчер восстановить приложение -------------------------------------------------- --------------------------------------------------
В документах говорится, что это связано с тем, что
Но у меня нет старых файлов:
root@connect:/var/discourse# ls /mnt/volume_ams3_01/shared/standalone/ резервные копии журнала letsencrypt postgres_backup postgres_data postgres_data_new postgres_run redis_data состояние ssl загрузки tmp
Еще две заметки:
- Папка
postgres_data
пуста. - У меня есть отдельная общая папка с использованием DigitalOceans Spaces.
Что я могу попытаться решить?
фитзи (Майкл Фитц-Пейн)
#2
Привет, Алекс,
Я не уверен, что вызывает цикл перезагрузки, но, возможно, вы сможете обойти это.
Содержит ли каталог postgres_data_new
вашу базу данных? Если да, проверьте PG_VERSION
в этом каталоге, чтобы проверить, работает ли обновление. Кроме того, полные журналы были бы полезны, если бы вы могли скопировать их.2 отметок «Нравится»
(Алекс Армстронг)
#3
Да, postgres_data_new
содержит мою базу данных, а PG_VERSION
в ней подтверждает, что версия 13
.
Не знаю, какими логами было бы полезно поделиться с вами (и где их найти).
#4
В этом случае вы сможете скопировать postgres_data_new
в каталог postgres_data
и выполнить перестроение. лаунчер
увидит, что база данных уже обновлена на PG13, и продолжит оттуда.
1 Нравится
(Алекс Армстронг)
#5
Привет, Майкл! Я забыл упомянуть, что с момента публикации здесь первоначально я пробовал это (дважды). Я все еще застрял в петле.
1 Нравится
(Алекс Армстронг)
#6
Я не знаю, как зафиксировать вывод ./launcher reboot app
, но вот что у меня получилось.
Начинается так:
root@connect:/var/discourse# ./launcher перестроить приложение Обеспечение актуальности лаунчера Получение источника Лаунчер обновлен Остановка старого контейнера + /usr/bin/docker stop -t 60 приложение приложение cd /pups && git pull && git checkout v1.0.3 && /pups/bin/pups --stdin Из https://github.com/discourse/pups 17f04ec..e0ff889мастер ->источник/мастер * [новый тег] v1.1.1 -> v1.1.1 * [новый тег] v1.1.0 -> v1.1.0 Обновление 17f04ec..e0ff889 Перемотка вперед .github/рабочие процессы/ci.yml | 29 ++++++ .github/рабочие процессы/lint.yml | 27 +++++ .rubocop.yml | 3 + гемфайл | 2 + Защитный файл | 4 +- README.md | 21 ++++ Рейкфайл | 14 +-- мусорное ведро / щенки | 8 +- библиотека/pups.rb | 32 ++++-- библиотека/щенки/cli.rb | 92 ++++++++++------- lib/pups/command. rb | 25 +++-- библиотека/щенки/config.rb | 240 +++++++++++++++++++++++++-------------------- lib/pups/docker.rb | 69 +++++++++++++ lib/pups/exec_command.rb | 182 ++++++++++++++++++---------------- lib/pups/file_command.rb | 60 +++++------ lib/pups/merge_command.rb | 94 ++++++++--------- lib/pups/replace_command.rb | 70 +++++++------ lib/pups/runit.rb | 47 +++++---- lib/щенков/версия.rb | 4 +- щенки.gemspec | 37 ++++--- тест/cli_test.rb | 102 +++++++++++++++--- тест/config_test.rb | 215 ++++++++++++++++++++++++++++++---------- тест/docker_test.rb | 157 ++++++++++++++++++++++++++++++++ тест/exec_command_test.rb | 62 ++++++----- тест/file_command_test.rb | 17++- тест/merge_command_test.rb | 64 ++++++------ тест/replace_command_test.rb | 86 ++++++++-------- тест/test_helper.rb | 2 + 28 файлов изменено, 1158 вставок(+), 607 удалений(-) режим создания 100644 .github/workflows/ci.yml режим создания 100644 .github/workflows/lint.yml создать режим 100644 .rubocop.yml режим создания 100644 lib/pups/docker. rb создать режим 100644 test/docker_test.rb Примечание: проверьте «v1.0.3». Вы находитесь в состоянии «отсоединенной HEAD». Вы можете осмотреться, сделать эксперимент изменения и зафиксировать их, и вы можете отказаться от любых коммитов, сделанных в этом состояние, не влияя на какие-либо ветки, выполнив еще одну проверку. Если вы хотите создать новую ветку для сохранения созданных вами коммитов, вы можете сделайте это (сейчас или позже), снова используя -b с командой checkout. Пример: git checkout -b <имя новой ветки> HEAD теперь на d1db030 вырезал новую версию Я, [2021-10-19T05:37:44.995716 #1] INFO -- : Загрузка --stdin I, [2021-10-19T05:37:45.001857 #1] ИНФОРМАЦИЯ -- : > locale-gen $LANG && update-locale I, [2021-10-19T05:37:45.031533 #1] ИНФОРМАЦИЯ -- : Создание локалей (это может занять некоторое время)... Генерация завершена. I, [2021-10-19T05:37:45.032260 #1] ИНФОРМАЦИЯ -- : > mkdir -p /shared/postgres_run Я, [2021-10-19T05:37:45.037403 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45. 038002 #1] ИНФОРМАЦИЯ -- : > chown postgres:postgres /shared/postgres_run Я, [2021-10-19T05:37:45.041480 #1] ИНФОРМАЦИЯ -- : Я, [2021-10-19T05:37:45.041974 #1] ИНФОРМАЦИЯ -- : > chmod 775 /shared/postgres_run Я, [2021-10-19T05:37:45.044313 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45.044759 #1] ИНФОРМАЦИЯ -- : > rm -fr /var/run/postgresql Я, [2021-10-19T05:37:45.047047 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45.047605 #1] ИНФОРМАЦИЯ -- : > ln -s /shared/postgres_run /var/run/postgresql Я, [2021-10-19T05:37:45.051062 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45.051463 #1] ИНФОРМАЦИЯ -- : > socat /dev/null UNIX-CONNECT:/shared/postgres_run/.s.PGSQL.5432 || exit 0 && echo postgres уже работает stop container ; выход 1 19.10.202105:37:45 socat[33] E connect(6, AF=1 "/shared/postgres_run/.s.PGSQL.5432", 36): Нет такого файла или каталога Я, [2021-10-19T05:37:45.058669 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45.058976 #1] ИНФОРМАЦИЯ -- : > rm -fr /shared/postgres_run/.s* Я, [2021-10-19T05:37:45. 061427 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45.061743 #1] ИНФОРМАЦИЯ -- : > rm -fr /shared/postgres_run/*.pid Я, [2021-10-19T05:37:45.063969 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45.064258 #1] ИНФОРМАЦИЯ -- : > mkdir -p /shared/postgres_run/13-main.pg_stat_tmp Я, [2021-10-19T05:37:45.068148 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45.068570 #1] ИНФОРМАЦИЯ -- : > chown postgres:postgres /shared/postgres_run/13-main.pg_stat_tmp Я, [2021-10-19T05:37:45.070400 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45.074243 #1] ИНФОРМАЦИЯ -- : Файл > /etc/service/postgres/run chmod: +x chown: I, [2021-10-19T05:37:45.077577 #1] ИНФОРМАЦИЯ -- : Файл > /etc/service/postgres/log/run chmod: +x chown: I, [2021-10-19T05:37:45.081084 #1] ИНФОРМАЦИЯ -- : Файл > /etc/runit/3.d/99-postgres chmod: +x chown: Я, [2021-10-19T05:37:45.084463 #1] ИНФОРМАЦИЯ -- : Файл > /root/upgrade_postgres chmod: +x chown: I, [2021-10-19T05:37:45.084841 #1] ИНФОРМАЦИЯ -- : > chown -R root /var/lib/postgresql/13/main Я, [2021-10-19T05:37:45. 766251 #1] ИНФОРМАЦИЯ -- : Я, [2021-10-19T05:37:45.766560 #1] ИНФОРМАЦИЯ -- : > [ ! -e /shared/postgres_data ] && install -d -m 0755 -o postgres -g postgres /shared/postgres_data && sudo -E -u postgres /usr/lib/postgresql/13/bin/initdb -D /shared/postgres_data | | выход 0 Я, [2021-10-19T05:37:45.769955 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45.770597 #1] ИНФОРМАЦИЯ -- : > chown -R postgres:postgres /shared/postgres_data Я, [2021-10-19T05:37:45.841916 #1] ИНФОРМАЦИЯ -- : I, [2021-10-19T05:37:45.842605 #1] ИНФОРМАЦИЯ -- : > chown -R postgres:postgres /var/run/postgresql Я, [2021-10-19T05:37:45.845109 #1] ИНФОРМАЦИЯ -- : Я, [2021-10-19T05:37:45.845574 #1] ИНФОРМАЦИЯ -- : > /root/upgrade_postgres initdb: предупреждение: включение «доверительной» аутентификации для локальных подключений Вы можете изменить это, отредактировав pg_hba.conf или используя опцию -A, или --auth-local и --auth-host, при следующем запуске initdb. debconf: задержка настройки пакета, так как apt-utils не установлен
Затем он проходит слишком быстро (много строк в /shared/postgres_data/base/whatever
и заканчивается так:
/shared/postgres_data/base/16400/203028 /общий/postgres_data/база/16400/203045 /общий/postgres_data/база/16400/203047 /общий/postgres_data/база/16400/203049 /общий/postgres_data/база/16400/203050 /общий/postgres_data/база/13014/2613 /общий/postgres_data/база/13014/2683 /общий/postgres_data/база/1/2613 /общий/postgres_data/база/1/2683 Ok Установка следующего OID для нового кластера в порядке Синхронизировать каталог данных с диском в порядке Создание скрипта для анализа нового кластера в порядке Создание скрипта для удаления старого кластера в порядке Обновление завершено ---------------- Статистика оптимизатора не передается pg_upgrade, поэтому как только вы запустите новый сервер, рассмотрите возможность запуска: . /analyze_new_cluster.sh Запуск этого скрипта удалит файлы данных старого кластера: ./delete_old_cluster.sh -------------------------------------------------- -------------------------------------------------- ОБНОВЛЕНИЕ POSTGRES ЗАВЕРШЕНО Старая база данных 10 хранится в /shared/postgres_data_old Чтобы завершить обновление, выполните повторную сборку, используя: ./лаунчер восстановить приложение -------------------------------------------------- -------------------------------------------------- a68ed0b1b54e4a0e2dae2543dc27d87be02ca1f81738e0d2e43511a46524a980
фитзи (Майкл Фитц-Пейн)
#7
Не могли бы вы поделиться шаблонами, которые вы включаете в containers/app.yml
?
Алехандроф (Алекс Армстронг)
#8
Конечно:
шаблоны: # - "templates/postgres.10.template.yml" - "шаблоны/postgres.13.template.yml" - "шаблоны/redis.template.yml" - "шаблоны/web.template.yml" - "шаблоны/web.ssl.template.yml" - "templates/web.letsencrypt.ssl.template.yml" - "templates/web.ratelimited.template.yml" - "templates/web.replygif.template.yml" # для плагина ReplyGIF: https://github.com/cpradio/discourse-plugin-replygif
(ответный gif я закомментирую, так как им все равно не пользуюсь.)
пфаффман (Джей Пфаффман)
#9
Алехандроф:
У меня есть отдельная общая папка с использованием DigitalOceans Spaces.
Что это значит? Я думаю, это может быть связано.
Алехандроф:
шаблоны/postgres.13.template.yml
Почему это не просто шаблон postgres без 13?
Возможно, проблема в этом.
1 Нравится
(Алекс Армстронг)
#10
Привет Джей!
пфаффман:
Алехандроф:
шаблоны/postgres.13.template.yml
Почему это не просто шаблон postgres без 13?
Вы правы, это ошибка, и она кажется вероятной причиной. Я изменил его на templates/postgres. template.yml
и дважды пересобрал, но все еще застрял в цикле.
пфаффман:
Алехандроф:
У меня есть отдельная общая папка с использованием DigitalOceans Spaces.
Что это значит? Я думаю, это может быть связано.
Я следовал этому руководству (еще когда оно было доступно), чтобы использовать DigitalOcean Spaces для резервного копирования и загрузки изображений.
Мои данные postgres находятся в двух местах:
-
/var/postgres_data_discourse
(PG_VERSION = 10) -
/mnt/volume_ams3_01/shared/standalone/postgres_data_new
(PG_VERSION = 13) -
/mnt/volume_ams3_01/shared/standalone/postgres_data
(PG_VERSION = 13) — эти файлы я скопировал вручную изpostgres_data_new
, как предлагалось ранее
пфаффман (Джей Пфаффман)
#11
В настоящее время мне кажется, что это как-то связано с отображением томов.
.
Алехандроф:
вар/postgres_data_discourse
(PG_VERSION = 10)/mnt/volume_ams3_01/shared/standalone/postgres_data_new
(PG_VERSION = 13)
Но вышеприведенное выглядит так, как будто у вас есть postgres, отдельный от postgres, который Discourse обновляет. Discourse не имеет ничего общего с postgres в /var/postgres_data_discourse. Может быть, вы пытались использовать свой собственный postgres, а не тот, который предоставляет Discourse? Это не похоже на стандартную установку.
1 Нравится
(Алекс Армстронг)
#12
Это стандартная установка 2016 года, и с тех пор она обновляется, так что, возможно, что-то изменилось за это время?
Для сопоставления томов я выполнил шаги, описанные в руководстве, на которое я ссылался выше.
Я не думаю, что пытался установить свой собственный postgres — я недостаточно техничен, чтобы понять, зачем мне это нужно
Я могу сказать, что у меня была «проблема с циклом», когда я пытался обновиться с postgres 10 до 12, и поэтому отложил это, чтобы поработать позже. На днях я вообще перестал перестраиваться, и из сообщений об ошибках я понял, что это связано с postgres, и поэтому попытался обновить, думая, что это может решить проблему.
Можно ли вернуться к шаблону postgres 10, чтобы увидеть, какие ошибки он выдает?
Редактировать: любые другие предложения приветствуются! Я не знаю, как поступить на этом этапе.
пфаффман (Джей Пфаффман)
№13
Алехандроф:
Могу сказать, что у меня была "проблема с петлей", когда я пытался обновиться с postgres 10 на 12,
Было бы неплохо упомянуть об этом в первом сообщении.
Алехандроф:
Редактировать: любые другие предложения приветствуются! Я не знаю, как поступить на этом этапе.
Я бы сделал чистую установку и восстановил последнюю резервную копию. Это самый простой путь вперед. Ваша ОС, скорее всего, тоже устарела.
2 отметок «Нравится»
(Алекс Армстронг)
№14
пфаффман:
Я бы сделал чистую установку и восстановил последнюю резервную копию. Это самый простой путь вперед. Ваша ОС, скорее всего, тоже устарела.
Кажется, решить одну проблему очень сложно, но, по крайней мере, это конкретный путь вперед. Спасибо, что помог мне справиться с этим, Джей!
пфаффман (Джей Пфаффман)
№15
Я не говорю, что другого выхода из вашего затруднительного положения нет, но такой кувалдный подход имеет высокую вероятность успеха и не требует специальных знаний. Есть куча крошечных вещей, которые я мог бы попробовать, если бы я был тем, кто это исправлял, но их все довольно сложно описать здесь, особенно когда неясно, какие из них попробовать и могут ли они работать.
Если эта система была настроена в 2016 году и до сих пор имеет эту ОС, то обновление ОС тоже не скоро, и ИМХО гораздо проще раскрутить новый сервер, чем делать обновление ОС (это может быть намного сейчас менее верно, чем 15 лет назад, когда я сформировал такое мнение!).