PSQL SET
Variablen werden nicht innerhalb von Zeichenfolgen in Dollar-Anführungszeichen interpoliert. Ich weiß es nicht genau, aber ich denke, es gibt keinen Ausweg oder andere Tricks, um SET
einzuschalten Variable Interpolation drin.
Man könnte meinen, Sie könnten einen nicht in Anführungszeichen gesetzten :user
einklemmen zwischen zwei in Dollar notierten Abschnitten von PL/pgSQL, um den gewünschten Effekt zu erzielen. Aber das scheint nicht zu funktionieren ... Ich denke, die Syntax erfordert eine einzelne Zeichenfolge und keinen Ausdruck, der Zeichenfolgen verkettet. Könnte mich da irren.
Jedenfalls spielt das keine Rolle. Es gibt einen anderen Ansatz (wie Pasco bemerkte):Schreiben Sie die gespeicherte Prozedur, um ein PL/pgSQL-Argument zu akzeptieren. So würde das aussehen.
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;
Hinweise zu dieser Funktion:
EXECUTE
generiert einen entsprechendenGRANT
bei jedem Aufruf mit unserem Prozedurargument. Der Abschnitt des PG-Handbuchs namens „Dynamische Befehle ausführen " erklärtEXECUTE
ausführlich.- Die Deklaration des Prozedurarguments
user
muss in doppelte Anführungszeichen gesetzt werden. Doppelte Anführungszeichen erzwingen die Interpretation als Bezeichner.
Sobald Sie die Funktion so definiert haben, können Sie sie mit interpolierten PSQL-Variablen aufrufen. Hier ist eine Gliederung.
- Führen Sie
psql --variable user="'whoever'" --file=myscript.sql
aus . Der Benutzername muss in einfache Anführungszeichen gesetzt werden! - Definieren Sie in myscript.sql die Funktion wie oben.
- Fügen Sie in myscript.sql
select foo(:user);
ein . Hier verlassen wir uns auf die einfachen Anführungszeichen, die wir in den Wert vonuser
setzen .
Obwohl dies zu funktionieren scheint, kommt es mir ziemlich squirrly vor. Ich dachte SET
Variablen waren für die Laufzeitkonfiguration vorgesehen. Daten in SET
herumtragen scheint seltsam.
Bearbeiten :Hier ist ein konkreter Grund, es nicht zu tun Verwenden Sie SET
Variablen. Aus der Manpage:"Diese Zuweisungen werden in einer sehr frühen Phase des Starts vorgenommen, sodass Variablen, die für interne Zwecke reserviert sind, später möglicherweise überschrieben werden." Wenn Postgres sich entschieden hat, eine Variable namens user
zu verwenden (oder was auch immer Sie wählen), es könnte Ihr Skriptargument mit etwas überschreiben, das Sie nie beabsichtigt haben. Tatsächlich nimmt psql bereits USER
für sich selbst – das funktioniert nur, weil SET
unterscheidet zwischen Groß- und Kleinschreibung. Das hätte fast von Anfang an alles kaputt gemacht!