Подстановка переменных внутри функций plpgsql - PullRequest
1 голос
/ 06 ноября 2019

Чтобы иметь возможность создавать различные экземпляры приложения в одной базе данных, как, например, этапы тестирования, я хотел бы использовать переменные для имени схемы. Все работает при создании таблиц или последовательностей, но я не могу придумать элегантный способ использования переменных внутри функций. Я уже читал некоторые статьи о строковых константах в кавычках, но все еще надеюсь найти решение.

В настоящее время работает PostgreSQL 11.

Вот код:

Работает как исключение, устанавливая schema_name в sc и используя переменную во время DDL:

\set schema_name sc

CREATE SEQUENCE :schema_name.S_VT_KEY INCREMENT BY 1 START WITH 1 CACHE 1 NO CYCLE OWNED BY NONE;

create table :schema_name.vartest (
  VT_KEY   BIGINT,
  DESCRIPTION TEXT);

А теперь функция:

create or replace function :schema_name.fvartest(
  p_desc  TEXT)
  RETURNS bigint
  language 'plpgsql'
  COST 100.0
  VOLATILE NOT LEAKPROOF
AS $function$
DECLARE
  p_key bigint;
BEGIN

  select nextval('sc.S_VT_KEY') into p_key; -- (1)

  insert into sc.vartest (VT_KEY, DESCRIPTION) -- (2)
      values (p_key, p_desc);

  return p_key;

END $function$;

В случае (1) я хотел бы использовать что-то вроде:

  select nextval(:schema_name || '.S_VT_KEY') into p_key;

В случае (2)

  insert into :schema_name.vartest (VT_KEY, DESCRIPTION) -- (2)

Любой вариант до сих пор выдает сообщение об ошибке:

Использование напрямую:

select nextval(:schema_name || '.S_VT_KEY') into p_key; 

отображает синтаксическую ошибку

psql:test/testcase001.sql:29: ERROR:  syntax error at or near ":"
LINE 12:  select nextval(:schema_name || '.S_VT_KEY') into p_key; -- ...

Экранирует, компилирует, но не запускает:

select nextval($e$:schema_name$e$ || '.S_VT_KEY') into p_key; -- (1)

CONTEXT:  SQL statement "select nextval($e$:schema_name$e$ || '.S_VT_KEY')"

Почти там, используя те же разделители, подставляет переменную, но отображает синтаксическую ошибку:

select nextval($function$ :'schema_name' $function$ || '.S_VT_KEY') into p_key; -- (1)

LINE 12:  select nextval($function$ 'sc' $function$ || '.S_VT_KEY')

Может быть, есть какой-нибудь способ в PostgreSQL 12?

1 Ответ

0 голосов
/ 11 ноября 2019

Я нашел решение, которое работает на данный момент, но далеко не так элегантно. Я использую подстановку переменных bash, и, похоже, это работает для двух упомянутых выше случаев:

#!/bin/bash

export schema_name="sc"

psql postgresql://<user>:<pwd>@<host>/<db>  << EOF


create or replace function ${schema_name}.fvartest(
  p_desc  TEXT)
  RETURNS bigint
  language 'plpgsql'
  COST 100.0
  VOLATILE NOT LEAKPROOF
AS \$function\$
DECLARE
    p_key bigint;
BEGIN

    select nextval('${schema_name}.S_VT_KEY') into p_key; -- (1)

    insert into ${schema_name}.vartest (VT_KEY, DESCRIPTION) -- (2)
        values (p_key, p_desc);

    return p_key;

END \$function\$;

    select ${schema_name}.fvartest('bla bla');
    select * from ${schema_name}.vartest;

EOF

Но теперь я должен поместить код в сценарий bash и избежать $ function $ Postges style $$нотации. Может быть, есть еще лучший способ, хотелось бы услышать от вас.

...