PSQL SET
zmienne nie są interpolowane wewnątrz ciągów w cudzysłowie. Nie wiem tego na pewno, ale myślę, że nie ma ucieczki ani innych sztuczek, aby włączyć SET
tam zmienna interpolacja.
Można by pomyśleć, że mógłbyś zaklinować nie cytowany :user
między dwoma odcinkami PL/pgSQL cytowanymi w dolarach, aby uzyskać pożądany efekt. Ale to nie działa... Myślę, że składnia wymaga pojedynczego ciągu, a nie wyrażenia łączącego ciągi. Może się co do tego mylić.
W każdym razie to nie ma znaczenia. Jest inne podejście (jak zauważył Pasco):napisz procedurę składowaną, aby akceptowała argument PL/pgSQL. Oto, jak by to wyglądało.
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;
Uwagi dotyczące tej funkcji:
EXECUTE
generuje odpowiedniGRANT
przy każdym wywołaniu przy użyciu naszego argumentu procedury. Sekcja podręcznika PG o nazwie "Wykonywanie dynamicznych poleceń " wyjaśniaEXECUTE
szczegółowo.- Deklaracja argumentu procedury
user
musi być w cudzysłowie. Podwójne cudzysłowy wymuszają interpretację jako identyfikator.
Gdy zdefiniujesz funkcję w ten sposób, możesz ją wywołać za pomocą interpolowanych zmiennych PSQL. Oto zarys.
- Uruchom
psql --variable user="'whoever'" --file=myscript.sql
. Wokół nazwy użytkownika wymagane są pojedyncze cudzysłowy! - W myscript.sql zdefiniuj funkcję jak powyżej.
- W myscript.sql umieść
select foo(:user);
. Tutaj polegamy na tych pojedynczych cudzysłowach, które umieszczamy w wartościuser
.
Chociaż wydaje się to działać, wydaje mi się, że jest to dość dziwaczne. Myślałem, że SET
zmienne były przeznaczone do konfiguracji środowiska uruchomieniowego. Noszenie danych w SET
wydaje się dziwne.
Edytuj :oto konkretny powód, dla którego nie użyj SET
zmienne. Ze strony podręcznika:„Te przypisania są wykonywane na bardzo wczesnym etapie uruchamiania, więc zmienne zarezerwowane do celów wewnętrznych mogą zostać później nadpisane”. Jeśli Postgres zdecydował się użyć zmiennej o nazwie user
(lub cokolwiek wybierzesz), może nadpisać argument skryptu czymś, czego nigdy nie zamierzałeś. W rzeczywistości psql już przyjmuje USER
dla siebie -- to działa tylko dlatego, że SET
uwzględnia wielkość liter. To prawie zepsuło wszystko od samego początku!