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:
EXECUTEgeneruje odpowiedniGRANTprzy każdym wywołaniu przy użyciu naszego argumentu procedury. Sekcja podręcznika PG o nazwie "Wykonywanie dynamicznych poleceń " wyjaśniaEXECUTEszczegółowo.- Deklaracja argumentu procedury
usermusi 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!