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

seguridad de subprocesos postgresql para tablas temporales

Las tablas temporales son visibles para todas las operaciones en la misma sesión. Entonces no puedes crear una tabla temporal del mismo nombre en la misma sesión antes de descartar el que existe (confirmar la transacción en su caso).

Es posible que desee utilizar:

CREATE TEMP TABLE tmptbl IF NOT EXISTS ...

Más sobre CREATE TABLE en el manual.

Tablas temporales únicas

Para hacer que la tabla temporal sea local por "subproceso" (en la misma sesión), debe usar nombres de tabla únicos . Una forma sería usar una SEQUENCE independiente y SQL dinámico, en un lenguaje de procedimiento como plpgsql o en una declaración DO (que es básicamente lo mismo sin almacenar una función.

Ejecute uno:

CREATE SEQUENCE myseq;

Usar:

DO $$
BEGIN
EXECUTE 'CREATE TABLE tmp' || nextval('myseq')  ||'(id int)';
END;
$$

Para conocer el último nombre de la tabla:

SELECT 'tmp' || currval('myseq');

O póngalo todo en una función plpgsql y devuelva la tabla o reutilice el nombre de la tabla.

Sin embargo, todos los comandos SQL adicionales deben ejecutarse dinámicamente, ya que las declaraciones SQL simples operan con identificadores codificados. Entonces, probablemente sea mejor ponerlo todo en una función plpgsql.

Identificación única para usar la misma tabla temporal

Otra posible solución podría ser usar la misma tabla temporal para todos los hilos en la misma sesión y agregue una columna thread_id a la mesa. Asegúrese de indexar la columna, si hace un uso intensivo de la función. Luego use un único thread_id por subproceso (en la misma sesión).

Una sola vez:

CREATE SEQUENCE myseq;

Una vez por hilo:

CREATE TEMP TABLE tmptbl(thread_id int, col1 int) IF NOT EXISTS;
my_id :=  nextval('myseq'); -- in plpgsql
-- else find another way to assign unique id per thread

SQL:

INSERT INTO tmptbl(thread_id, col1) VALUES
(my_id, 2), (my_id, 3), (my_id, 4);

SELECT * FROM tmptbl WHERE thread_id = my_id;