Rengör installationen:
CREATE TABLE tbl (
given_date date
, set_name varchar
);
Använd en singular term som kolumnnamn för en singular värde.
Datatypen är uppenbarligen date
och inte en timestamp
.
För att omvandla dina textparametrar till en användbar tabell:
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;
"Parallell unnest" är behändig men har sina varningar. Postgres 9.4 lägger till en ren lösning, Postgres 10 så småningom sanerade beteendet av detta. Se nedan.
Dynamiskt utförande
Förberett uttalande
Förberedda uttalanden är endast synliga för den skapande sessionen och dör med den. Per dokumentation:
Förberedda satser varar bara under den aktuella databassessionen.
PREPARE
en gång per session :
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;
Eller använd verktyg från din klient för att förbereda uttalandet.
Kör n gånger med godtyckliga parametrar:
EXECUTE upd_tbl('2001-01-01to2001-01-05,2001-01-10to2001-01-15', 's1,s4');
Serversidans funktion
Funktioner kvarstår och är synliga för alla sessioner.
CREATE FUNCTION
en gång :
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;
Ring n gånger:
SELECT f_upd_tbl('2001-01-01to2001-01-05,2001-01-20to2001-01-25', 's2,s5');
SQL Fiddle
Överlägsen design
Använd arrayparametrar (kan fortfarande tillhandahållas som strängliteral), ett daterange
typ (både sid 9.3) och den nya parallella unnest()
(sid 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;
<@
är operatorn "elementet ingår av".
Ring:
SELECT f_upd_tbl('{"[2001-01-01,2001-01-05]"
,"[2001-01-20,2001-01-25]"}', '{s2,s5}');
Detaljer:
- Ta bort flera arrayer parallellt