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
променливи. От страницата на ръководството:„Тези присвоявания се извършват по време на много ранен етап на стартиране, така че променливите, запазени за вътрешни цели, може да бъдат презаписани по-късно.“ Ако Postgres реши да използва променлива с име user
(или каквото и да изберете), може да замени аргумента на скрипта ви с нещо, което никога не сте възнамерявали. Всъщност psql вече приема USER
за себе си -- това работи само защото SET
е чувствителен към главни и малки букви. Това почти провали нещата от самото начало!