sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Hay alguna sintaxis de escape para la variable psql dentro de las funciones de PostgreSQL?

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:

  1. EXECUTE genera un GRANT 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 " explica EXECUTE en detalle.
  2. 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.

  1. Ejecute psql --variable user="'whoever'" --file=myscript.sql . ¡Se requieren comillas simples alrededor del nombre de usuario!
  2. En myscript.sql, defina la función como arriba.
  3. En myscript.sql, coloque select foo(:user); . Aquí es donde confiamos en esas comillas simples que ponemos en el valor de user .

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!