PSQL SET
las variables no se interpolan dentro de cadenas cotizadas en dólares. No lo sé con certeza, pero creo que no hay escapatoria u otros trucos para activar SET
interpolación variable allí.
Uno podría pensar que podría bloquear un :user
sin comillas entre dos tramos cotizados en dólares de PL/pgSQL para obtener el efecto deseado. Pero esto no parece funcionar... Creo que la sintaxis requiere una sola cadena y no una expresión que concatene cadenas. Podría estar equivocado en eso.
De todos modos, eso no importa. Hay otro enfoque (como señaló Pasco):escriba el procedimiento almacenado para aceptar un argumento PL/pgSQL. Así es como se vería.
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;
Notas sobre esta función:
EXECUTE
genera unGRANT
apropiado en cada invocación usando nuestro argumento de procedimiento. La sección del manual de PG se llama "Ejecución de comandos dinámicos " explicaEXECUTE
en detalle.- La declaración del argumento del procedimiento
user
debe estar entre comillas dobles. Las comillas dobles obligan a que se interprete como un identificador.
Una vez que defina la función de esta manera, puede llamarla usando variables PSQL interpoladas. Aquí hay un esquema.
- Ejecute
psql --variable user="'whoever'" --file=myscript.sql
. ¡Se requieren comillas simples alrededor del nombre de usuario! - En myscript.sql, defina la función como arriba.
- En myscript.sql, coloque
select foo(:user);
. Aquí es donde confiamos en esas comillas simples que ponemos en el valor deuser
.
Aunque esto parece funcionar, me parece bastante complicado. Pensé SET
Las variables estaban destinadas a la configuración en tiempo de ejecución. Transportar datos en SET
parece extraño.
Editar :aquí hay una razón concreta para no usa SET
variables De la página de manual:"Estas asignaciones se realizan durante una etapa muy temprana del inicio, por lo que las variables reservadas para fines internos pueden sobrescribirse más tarde". Si Postgres decidiera usar una variable llamada user
(o lo que elijas), podría sobrescribir el argumento de tu script con algo que nunca quisiste. De hecho, psql ya toma USER
por sí mismo, esto solo funciona porque SET
distingue entre mayúsculas y minúsculas. ¡Esto casi rompe las cosas desde el principio!