PSQL SET proměnné nejsou interpolovány uvnitř řetězců v dolarech. Nevím to jistě, ale myslím, že neexistuje žádný únik nebo jiný trik, jak zapnout SET proměnná interpolace.
Někdo by si mohl myslet, že byste mohli zaklínit neuvedený :user mezi dvěma dolarovými kotovanými úseky PL/pgSQL, abyste dosáhli požadovaného efektu. Ale zdá se, že to nefunguje... Myslím, že syntaxe vyžaduje jeden řetězec a ne výraz spojující řetězce. V tom se můžete mýlit.
Každopádně na tom nezáleží. Existuje další přístup (jak poznamenal Pasco):napište uloženou proceduru tak, aby přijala argument PL/pgSQL. Zde je návod, jak by to vypadalo.
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;
Poznámky k této funkci:
EXECUTEvygeneruje vhodnýGRANTpři každém vyvolání pomocí našeho argumentu procedury. Část příručky PG s názvem "Provádění dynamických příkazů “ vysvětlujeEXECUTEpodrobně.- Argument deklarace procedury
usermusí být uvozováno dvakrát. Dvojité uvozovky nutí, aby byl interpretován jako identifikátor.
Jakmile funkci definujete takto, můžete ji volat pomocí interpolovaných proměnných PSQL. Zde je přehled.
- Spusťte
psql --variable user="'whoever'" --file=myscript.sql. U uživatelského jména jsou povinné jednoduché uvozovky! - V souboru myscript.sql definujte funkci jako výše.
- Do souboru myscript.sql vložte
select foo(:user);. Zde se spoléháme na ty jednoduché uvozovky, které vkládáme do hodnotyuser.
I když se zdá, že to funguje, připadá mi to spíše jako veverka. Myslel jsem SET proměnné byly určeny pro konfiguraci za běhu. Přenášení dat v SET vypadá divně.
Upravit :zde je konkrétní důvod, proč ne použijte SET proměnné. Z manuálové stránky:"Tato přiřazení se provádí během velmi rané fáze spouštění, takže proměnné vyhrazené pro interní účely mohou být později přepsány." Pokud se Postgres rozhodl použít proměnnou s názvem user (nebo cokoli, co si vyberete), může to přepsat váš argument skriptu něčím, co jste nikdy nezamýšleli. Ve skutečnosti psql již bere USER pro sebe -- to funguje pouze proto, že SET rozlišuje velká a malá písmena. Tohle málem rozbilo věci od začátku!