Как использовать переменную в скриптах Postgres? - PullRequest
0 голосов
/ 20 ноября 2018

Я работаю над прототипом, который использует Postgres в качестве бэкэнда.Я не делаю много SQL, поэтому я чувствую свой путь через это.Я создал .pgsql файл, который я запускаю с psql, который выполняет каждый из множества файлов, которые устанавливают мою базу данных, и я использую переменную для определения схемы, которая будет использоваться, чтобы я мог тестировать функции, не испортив свое «добро»Экземпляр:

\set schema_name 'example_schema'

\echo 'The Schema name is' :schema_name

\ir sql/file1.pgsql
\ir sql/file2.pgsql

Это работает хорошо.Я определил несколько функций, которые правильно расширяют :schema_name:

CREATE OR REPLACE FUNCTION :schema_name.get_things_by_category(...

По причинам, которые я не могу понять, это не работает в моей новейшей функции:

CREATE OR REPLACE FUNCTION :schema_name.update_thing_details(_id uuid, _details text)
    RETURNS text
    LANGUAGE 'plpgsql'
AS $BODY$

BEGIN
    UPDATE :schema_name.things
    ...

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

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Я могу придумать три подхода, поскольку psql не может сделать это напрямую.

Сценарий оболочки

Использование сценария bash для выполнения подстановки переменной и конвейерарезультаты в psql, например.

#!/bin/bash

$schemaName = $1
$contents = `cat script.sql | sed -e 's/@SCHEMA_NAME@/$schemaName'`

echo $contents | psql

Вероятно, это будет много, если у вас много сценариев .sql.

Схема организации

Сохраните подход, который вы используете сейчас, с жестко запрограммированной схемой чего-то вроде staging, а затем используйте сценарий bash, перейдите и переименуйте staging в любое место, где вы хотите, чтобы действительная схема была.

Настроить путь поиска

Ваша точка входа может быть встроенным скриптом в bash, который передается в psql, выполняет предварительное обновление схемы соединения по умолчанию, а затем использует \Чтобы включить все ваши файлы .sql, которые не должны указывать схему.

#!/bin/bash

$schemaName = $1

psql <<SCRIPT
SET search_path TO $schemaName;
\ir sql/file1.pgsql
\ir sql/file2.pgsql
SCRIPT

Некоторые сведения: Как выбрать схему в postgres при использовании psql?

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

0 голосов
/ 21 ноября 2018

Документация гласит:

Переменная интерполяция не будет выполняться внутри указанных в кавычках литералов и идентификаторов SQL.Следовательно, такая конструкция, как ':foo', не работает для получения заключенного в кавычки литерала из значения переменной (и было бы небезопасно, если бы это работало, поскольку она не будет правильно обрабатывать кавычки, встроенные в значение).

Теперь телом функции является «% -ая цитата доллара»;строковый литерал ($BODY$...$BODY$), поэтому переменная не будет там заменена.

Я не могу придумать, как это сделать с помощью psql переменных.

...