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

Divida la cadena dada y prepare la declaración del caso

Configuración limpia:

CREATE TABLE tbl (
  given_date date
, set_name varchar
);

Use un término singular como nombre de columna para un simple value.
El tipo de datos es obviamente date y no una timestamp .

Para transformar sus parámetros de texto en una tabla útil:

SELECT unnest(string_to_array('2001-01-01to2001-01-05,2001-01-10to2001-01-15', ',')) AS date_range
     , unnest(string_to_array('s1,s2', ',')) AS set_name;

"Parallel unnest" es útil pero tiene sus advertencias. PostgreSQL 9.4 agrega una solución limpia, Postgres 10 finalmente desinfectado el comportamiento de este. Ver más abajo.

Ejecución dinámica

Declaración preparada

Las declaraciones preparadas solo son visibles para la sesión de creación y mueren con ella. Por documentación:

Las declaraciones preparadas solo duran la duración de la sesión actual de la base de datos.

PREPARE una vez por sesión :

PREPARE upd_tbl AS
UPDATE tbl t
SET    set_name = s.set_name
FROM  (
   SELECT unnest(string_to_array($1, ',')) AS date_range
        , unnest(string_to_array($2, ',')) AS set_name
   ) s
WHERE t.given_date BETWEEN split_part(date_range, 'to', 1)::date
                       AND split_part(date_range, 'to', 2)::date;

O use las herramientas provistas por su cliente para preparar la declaración.
Ejecutar n veces con parámetros arbitrarios:

EXECUTE upd_tbl('2001-01-01to2001-01-05,2001-01-10to2001-01-15', 's1,s4');

Función del lado del servidor

Las funciones se conservan y son visibles para todos sesiones.

CREATE FUNCTION una vez :

CREATE OR REPLACE FUNCTION f_upd_tbl(_date_ranges text, _names text)
  RETURNS void AS
$func$
UPDATE tbl t
SET    set_name = s.set_name
FROM  (
   SELECT unnest(string_to_array($1, ',')) AS date_range
        , unnest(string_to_array($2, ',')) AS set_name
   ) s
WHERE  t.given_date BETWEEN split_part(date_range, 'to', 1)::date
                        AND split_part(date_range, 'to', 2)::date
$func$  LANGUAGE sql;

Llamar n veces:

SELECT f_upd_tbl('2001-01-01to2001-01-05,2001-01-20to2001-01-25', 's2,s5');

Violín SQL

Diseño superior

Use parámetros de matriz (todavía se pueden proporcionar como cadenas literales), un daterange type (ambos pg 9.3) y el nuevo paralelo unnest() (pág. 9.4 ).

CREATE OR REPLACE FUNCTION f_upd_tbl(_dr daterange[], _n text[])
  RETURNS void AS
$func$
UPDATE tbl t
SET    set_name = s.set_name
FROM   unnest($1, $2) s(date_range, set_name)
WHERE  t.given_date <@ s.date_range
$func$  LANGUAGE sql;

<@ siendo el operador "el elemento está contenido por".

Llamar:

SELECT f_upd_tbl('{"[2001-01-01,2001-01-05]"
                  ,"[2001-01-20,2001-01-25]"}', '{s2,s5}');

Detalles:

  • Desanime varios arreglos en paralelo