Чиста настройка:
CREATE TABLE tbl (
given_date date
, set_name varchar
);
Използвайте термин в единствено число като име на колона за единично стойност.
Типът данни очевидно е date
а не timestamp
.
За да трансформирате вашите текстови параметри в полезна таблица:
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“ е удобен, но има своите предупреждения. Postgres 9.4 добавя чисто решение, Postgres 10 в крайна сметка санкционира поведението на това. Вижте по-долу.
Динамично изпълнение
Подготвено изявление
Подготвените изявления са видими само за създаващата сесия и умират с нея. По документация:
Подготвените оператори са валидни само за продължителността на текущата сесия на базата данни.
PREPARE
веднъж на сесия :
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;
Или използвайте инструменти, предоставени от вашия клиент, за да подготвите изявлението.
Изпълнете n пъти с произволни параметри:
EXECUTE upd_tbl('2001-01-01to2001-01-05,2001-01-10to2001-01-15', 's1,s4');
Функция от страна на сървъра
Функциите се запазват и се виждат за всички сесии.
CREATE FUNCTION
веднъж :
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;
Обадете се n пъти:
SELECT f_upd_tbl('2001-01-01to2001-01-05,2001-01-20to2001-01-25', 's2,s5');
SQL Fiddle
Превъзходен дизайн
Използвайте параметри на масива (все още могат да бъдат предоставени като низови литерали), daterange
тип (и двете стр. 9.3) и новия паралел unnest()
(стр. 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;
<@
е операторът "елементът се съдържа от".
Обадете се:
SELECT f_upd_tbl('{"[2001-01-01,2001-01-05]"
,"[2001-01-20,2001-01-25]"}', '{s2,s5}');
Подробности:
- Отвържете паралелно множество масиви