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