PostgreSQL - заставить файл .sql завершиться, если условие истинно, не запускать строки в (при обработке с помощью bash) - PullRequest
0 голосов
/ 15 мая 2018

Я обрабатываю .sql файлы с помощью bash автоматически в моем CI-решении в цикле for, чтобы отследить ошибочные миграции перед развертыванием.

MIGS - это массив bash, содержащий во времени порядок .sql в папке

for sqlfile in ${MIGS[@]};
do
    psql myproject_unit < $sqlfile
done

Есть ли способ прекратить обработку .sql, если условие выполнено?

Итак, что я делаю сейчас:

файл sql20180515n.sql

CREATE TABLE IF NOT EXISTS something (
...
/* imagine here other 400 lines of SQL */

Что я ищу (замените первые две строки на правильный синтаксис, если применимо, или скажите, если это невозможно)

IF TABLE_EXISTS(something) /* we already ran, no need */
EXIT;

CREATE TABLE something (
...
/* imagine here other 400 lines of SQL */

Итак, чтобы подтвердить: если условие выполнено (таблица / столбец / триггер / индекс уже существует), я бы хотел перейти к следующему источнику .sql в цикле my for, поэтому не закрывайте всю оболочку, только psql процессор, как определено в файле .sql, когда его завершать.

Ответы [ 3 ]

0 голосов
/ 15 мая 2018

PlPgsql сортирует его, мы используем следующий код, чтобы использовать в качестве примера для начала.

-- USE THIS AS EXAMPLE CODE FOR CREATING MORE COMPLEX TABLE STRUSCTURES NEVER TO BE DEFINED TWICE

CREATE OR REPLACE FUNCTION install_these_tables()
RETURNS INT AS $$

DECLARE

  does_exist int;

BEGIN

SELECT COUNT(*) as cnt INTO does_exist from pg_tables where tablename = 'testtable'; -- REPLACE TABLE NAME

  IF does_exist = 1 THEN
    RAISE NOTICE 'Existed';
    RETURN 1;
  ELSE
    -- REPLACE START
    CREATE TABLE testtable (
      id_testtable bigserial PRIMARY KEY,
      status text DEFAULT NULL
    );
    -- REPLACE END
    RAISE NOTICE 'Not existed, created';
    RETURN 0;
  END IF;

END; $$ LANGUAGE plpgsql;

SELECT install_these_tables();
DROP FUNCTION install_these_tables();

Также PostgreSQL 10 поддерживает \ if, но мы используем 9.6 и также не можем легко изменить примеры кодов для этого

0 голосов
/ 15 мая 2018

Другие ответы хороши, но, возможно, вы бы предпочли сохранить свою логику в оболочке.

Вы можете запросить условие в отдельном вызове psql.

В следующем примере я проверяю наличие таблицы something:

psql -d mydb -c "SELECT 'something'::regclass" >/dev/null 2>&1
# run the script only if the above errors out
if [ $? -ne 0 ]; then
    # create "something" since it doesn't exist
    psql -d mydb -1 -f create_something.sql
    if [ $? -ne 0 ]; then
        # exit with error if script fails
        exit 1
    fi
fi
0 голосов
/ 15 мая 2018

вам, скорее всего, понадобится логика plpgsql и, следовательно, оператор DO, ниже приведен пример:

MacBook-Air:Downloads vao$ psql so << EOF
>  do \$\$
>  begin
>   if (select count(*) from pg_class where oid = 'public.t'::regclass and relkind = 'r') > 0 then
>  insert into t values(1);
>  update t set i = 9 where i = 1;
>  end if;
>  end;
>  \$\$;
> select * from t;
> EOF
Timing is on.
Pager usage is off.
DO
Time: 8.952 ms
 i
---
 9
 9
 9
(3 rows)
...