sql >> Database teknologi >  >> RDS >> PostgreSQL

Er der nogen undvigende syntaks for psql-variabel inde i PostgreSQL-funktioner?

PSQL SET variabler interpoleres ikke inde i strenge med citerede dollars. Jeg ved det ikke med sikkerhed, men jeg tror, ​​der ikke er nogen flugt eller andet trick for at slå SET til variabel interpolation derinde.

Man kunne tro, at du kunne kile en uciteret :user mellem to dollar-noterede strækninger af PL/pgSQL for at få den ønskede effekt. Men dette ser ikke ud til at virke... Jeg tror, ​​at syntaksen kræver en enkelt streng og ikke et udtryk, der sammenkæder strenge. Kan tage fejl af det.

Det betyder i hvert fald ikke noget. Der er en anden tilgang (som Pasco bemærkede):skriv den lagrede procedure for at acceptere et PL/pgSQL-argument. Sådan ser det ud.

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;

Bemærkninger om denne funktion:

  1. EXECUTE genererer en passende GRANT på hver påkaldelse ved hjælp af vores procedureargument. PG-manualafsnittet kaldet "Udførelse af dynamiske kommandoer " forklarer EXECUTE i detaljer.
  2. Procedureerklæringsargumentet user skal citeres dobbelt. Dobbelte anførselstegn tvinger det til at blive fortolket som en identifikator.

Når du har defineret funktionen som denne, kan du kalde den ved hjælp af interpolerede PSQL-variabler. Her er en oversigt.

  1. Kør psql --variable user="'whoever'" --file=myscript.sql . Enkelte citater er påkrævet omkring brugernavnet!
  2. I myscript.sql skal du definere funktion som ovenfor.
  3. Indsæt select foo(:user); i myscript.sql . Det er her, vi stoler på de enkelte citater, vi sætter i værdien af ​​user .

Selvom det ser ud til at virke, virker det temmelig skurrende. Jeg tænkte SET variabler var beregnet til runtime-konfiguration. Transporterer data rundt i SET virker underligt.

Rediger :her er en konkret grund til at ikke brug SET variabler. Fra manpage:"Disse opgaver udføres i et meget tidligt trin af opstarten, så variabler reserveret til interne formål kan blive overskrevet senere." Hvis Postgres besluttede at bruge en variabel ved navn user (eller hvad du end vælger), kan det overskrive dit script-argument med noget, du aldrig havde tænkt dig. Faktisk tager psql allerede USER for sig selv -- dette virker kun fordi SET er store og små bogstaver. Dette gik næsten i stykker fra starten!



  1. Sum kolonner eller ny kolonne

  2. Top 10 interessante fakta og tips om MySQL

  3. Formater tal til 2 decimaler

  4. Skinner omfang - hvor i nøjagtige matcher