PSQL SET
переменные не интерполируются внутри строк в кавычках.Я не знаю этого наверняка, но я думаю, что нет никакого выхода или другой хитрости, чтобы включить там SET
переменную интерполяцию.
Можно подумать, что вы могли бы втиснуть :user
без кавычек между двумякавычки PL / pgSQL, чтобы получить желаемый эффект.Но, похоже, это не работает ... Я думаю, что синтаксис требует единственной строки, а не выражения, объединяющего строки.Могу ошибиться.
В любом случае, это не имеет значения.Есть другой подход (как отметил Паско): написать хранимую процедуру для принятия аргумента PL / pgSQL.Вот как это будет выглядеть.
CREATE OR REPLACE FUNCTION foo("user" TEXT) RETURNS void AS
$$
BEGIN
EXECUTE 'GRANT SELECT ON my_table TO GROUP ' || quote_ident(user);
END;
$$ LANGUAGE plpgsql;
Примечания к этой функции:
EXECUTE
генерирует соответствующий GRANT
при каждом вызове, используя наш аргумент процедуры.В разделе руководства PG под названием « Выполнение динамических команд » подробно объясняется EXECUTE
. - Объявление аргумента процедуры
user
должно заключаться в двойные кавычки.Двойные кавычки заставляют его интерпретировать как идентификатор.
Как только вы определили функцию, подобную этой, вы можете вызывать ее с помощью интерполированных переменных PSQL.Вот схема.
- Выполнить
psql --variable user="'whoever'" --file=myscript.sql
.Вокруг имени пользователя требуются одинарные кавычки! - В myscript.sql определите функцию, как указано выше.
- В myscript.sql введите
select foo(:user);
.Здесь мы полагаемся на те одинарные кавычки, которые мы помещаем в значение user
.
Хотя это, кажется, работает, мне кажется довольно коротким.Я думал, что SET
переменные предназначены для настройки во время выполнения.Перенос данных в SET
кажется странным.
Редактировать : вот конкретная причина, по которой не используют SET
переменные.С man-страницы: «Эти назначения выполняются на очень ранней стадии запуска, поэтому переменные, зарезервированные для внутренних целей, могут быть перезаписаны позже».Если Postgres решит использовать переменную с именем user
(или что-то еще, что вы выберете), он может перезаписать ваш аргумент сценария чем-то, что вы никогда не предполагали.Фактически, psql уже берет USER
для себя - это работает только потому, что SET
чувствителен к регистру.Это почти сломало вещи с самого начала!