PSQL SET
le variabili non sono interpolate all'interno di stringhe tra virgolette. Non lo so per certo, ma penso che non ci sia via di scampo o altri trucchi per attivare SET
interpolazione variabile lì dentro.
Si potrebbe pensare che potresti inserire un :user
senza virgolette tra due tratti di PL/pgSQL quotati in dollari per ottenere l'effetto desiderato. Ma questo non sembra funzionare ... Penso che la sintassi richieda una singola stringa e non un'espressione che concatena le stringhe. Potrebbe essere sbagliato.
Comunque, non importa. C'è un altro approccio (come ha notato Pasco):scrivere la procedura memorizzata per accettare un argomento PL/pgSQL. Ecco come sarebbe.
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;
Note su questa funzione:
EXECUTE
genera unGRANT
appropriato su ogni invocazione usando sul nostro argomento di procedura. La sezione del manuale PG denominata "Esecuzione di comandi dinamici " spiegaEXECUTE
in dettaglio.- La dichiarazione dell'argomento della procedura
user
deve essere doppiato. Le virgolette doppie ne obbligano a essere interpretate come un identificatore.
Una volta definita la funzione in questo modo, è possibile chiamarla utilizzando variabili PSQL interpolate. Ecco uno schema.
- Esegui
psql --variable user="'whoever'" --file=myscript.sql
. Sono necessarie virgolette singole attorno al nome utente! - In myscript.sql, definisci la funzione come sopra.
- In myscript.sql, inserisci
select foo(:user);
. È qui che ci affidiamo a quelle virgolette singole che mettiamo nel valore diuser
.
Anche se questo sembra funzionare, mi sembra piuttosto scoiattolo. Ho pensato SET
le variabili erano destinate alla configurazione di runtime. Portare i dati in giro in SET
sembra strano.
Modifica :ecco un motivo concreto per non usa SET
variabili. Dalla manpage:"Questi compiti vengono eseguiti durante una fase iniziale dell'avvio, quindi le variabili riservate per scopi interni potrebbero essere sovrascritte in seguito." Se Postgres ha deciso di utilizzare una variabile denominata user
(o qualunque cosa tu scelga), potrebbe sovrascrivere l'argomento dello script con qualcosa che non avresti mai voluto. In effetti, psql accetta già USER
per sé -- funziona solo perché SET
fa distinzione tra maiuscole e minuscole. Questo ha quasi rotto le cose dall'inizio!