Función de Postgresql para crear una tabla con un nombre de tabla dinámico.
Digamos que tengo varios usuarios, cada uno con su propio conjunto de contactos. Los usuarios pueden seleccionar qué terceros tienen acceso a sus contactos.
Podría crear una tabla de contactos grande y tener una columna de ‘propietario’ para identificar a qué usuarios pertenecen los contactos. Sin embargo, luego tendría que mantener permisos a nivel de fila para restringir qué terceros tienen o no tienen acceso a contactos de usuarios específicos.
En cambio, creo que (y podría estar equivocado aquí) tiene más sentido tener una tabla de contactos para cada usuario, por ejemplo: contact_e878df81_eba1_4a61_b592_30ac7100362a
. Luego podría administrar los permisos en una tabla separada.
Para crear estas ‘tablas de contactos dinámicas’, tengo la siguiente función:
CREATE OR REPLACE FUNCTION create_contact_table(IN tbl_name text) RETURNS INT AS $$
DECLARE
table_name text;
BEGIN
table_name = tbl_name;
create table IF NOT EXISTS table_name
(
id serial not null
constraint test_pkey
primary key,
firstname varchar not null,
lastname varchar not null,
age int not null,
address varchar not null,
email varchar not null,
created timestamp default CURRENT_TIMESTAMP
);
alter table table_name
owner to postgres;
RETURN 1;
END ;
$$ LANGUAGE plpgsql;
Cuando ejecuto la función (create_contact_table(contact_e878df81_eba1_4a61_b592_30ac7100362a)
), se crea la tabla, pero el nombre de la tabla es table_name
…
¿Por qué sucede eso? ¿Cómo puedo solucionarlo para que el nombre de la tabla sea correcto?
davy.ai
El problema es que el enunciado
CREATE TABLE
está utilizando la cadena de caracteres'table_name'
en lugar de la variabletable_name
como nombre de la tabla. Para solucionar esto, puedes utilizar SQL dinámico envolviendo la declaraciónCREATE TABLE
enEXECUTE
y utilizando marcadores de posición para el nombre de la tabla:Esto utiliza el especificador de formato
%I
para insertar de forma segura la variabletable_name
como un identificador en la declaración SQL.Con este cambio, la función
create_contact_table
debería crear la tabla con el nombre correcto.