PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Dividi la stringa data e prepara l'istruzione case

Configurazione pulita:

CREATE TABLE tbl (
  given_date date
, set_name varchar
);

Usa un termine singolare come nome di colonna per un singolo value.
Il tipo di dati è ovviamente date e non un timestamp .

Per trasformare i tuoi parametri di testo in una tabella utile:

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" è utile ma ha i suoi avvertimenti. Postgres 9.4 aggiunge una soluzione pulita, Postgres 10 alla fine ha disinfettato il comportamento di questo. Vedi sotto.

Esecuzione dinamica

Dichiarazione preparata

Le dichiarazioni preparate sono visibili solo alla sessione di creazione e muoiono con essa. Per documentazione:

Le dichiarazioni preparate durano solo per la durata della sessione del database corrente.

PREPARE una volta per sessione :

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;

Oppure usa gli strumenti forniti dal tuo cliente per preparare la dichiarazione.
Esegui n volte con parametri arbitrari:

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

Funzione lato server

Le funzioni sono persistenti e visibili a tutti sessioni.

CREATE FUNCTION una volta :

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;

Chiama n volte:

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

SQL Fiddle

Design superiore

Usa i parametri dell'array (può ancora essere fornito come stringhe letterali), un daterange type (entrambi pg 9.3) e il nuovo parallelo unnest() (pag 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;

<@ essendo l'operatore "l'elemento è contenuto da".

Chiama:

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

Dettagli:

  • Disnida più array in parallelo