Ren opsætning:
CREATE TABLE tbl (
given_date date
, set_name varchar
);
Brug et enkelt udtryk som kolonnenavn for en enkelt værdi.
Datatypen er tydeligvis date
og ikke et timestamp
.
Sådan transformerer du dine tekstparametre til en nyttig tabel:
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" er praktisk, men har sine forbehold. Postgres 9.4 tilføjer en ren løsning, Postgres 10 til sidst rensede denne adfærd. Se nedenfor.
Dynamisk udførelse
Udarbejdet erklæring
Forberedte udsagn er kun synlige for oprettelsessessionen og dør med det. Per dokumentation:
Forberedte udsagn varer kun i varigheden af den aktuelle databasesession.
PREPARE
én gang pr. 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 brug værktøjer leveret af din klient til at forberede erklæringen.
Udfør n gange med vilkårlige parametre:
EXECUTE upd_tbl('2001-01-01to2001-01-05,2001-01-10to2001-01-15', 's1,s4');
Server-side funktion
Funktioner bevares og er synlige for alle sessioner.
CREATE FUNCTION
en gang :
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 gange:
SELECT f_upd_tbl('2001-01-01to2001-01-05,2001-01-20to2001-01-25', 's2,s5');
SQL Fiddle
Supert design
Brug array-parametre (kan stadig leveres som streng-literal), et daterange
type (både s. 9.3) og den nye parallelle unnest()
(s. 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;
<@
er "elementet er indeholdt af" operatoren.
Ring til:
SELECT f_upd_tbl('{"[2001-01-01,2001-01-05]"
,"[2001-01-20,2001-01-25]"}', '{s2,s5}');
Detaljer:
- Unnest flere arrays parallelt