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:
EXECUTE
vygeneruje vhodnýGRANT
př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ětlujeEXECUTE
podrobně.- Argument deklarace procedury
user
musí 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!