Configuração limpa:
CREATE TABLE tbl (
given_date date
, set_name varchar
);
Use um termo singular como nome de coluna para um único value.
O tipo de dados é obviamente
date
e não um timestamp
. Para transformar seus parâmetros de texto em uma tabela útil:
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;
"Desaninhamento paralelo" é útil, mas tem suas ressalvas. Postgres 9.4 adiciona uma solução limpa, Postgres 10 eventualmente higienizado o comportamento deste. Ver abaixo.
Execução dinâmica
Declaração preparada
As declarações preparadas são visíveis apenas para a sessão de criação e morrem com ela. Por documentação:
As instruções preparadas duram apenas pela duração da sessão atual do banco de dados.
PREPARE
uma vez por sessão :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;
Ou use ferramentas fornecidas pelo seu cliente para preparar a declaração.
Execute n vezes com parâmetros arbitrários:
EXECUTE upd_tbl('2001-01-01to2001-01-05,2001-01-10to2001-01-15', 's1,s4');
Função do lado do servidor
As funções são persistentes e visíveis para todos sessões.
CREATE FUNCTION
uma vez :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;
Ligue n vezes:
SELECT f_upd_tbl('2001-01-01to2001-01-05,2001-01-20to2001-01-25', 's2,s5');
Fiddle SQL
Design superior
Use parâmetros de matriz (ainda podem ser fornecidos como literais de string), um
daterange
type (ambos da página 9.3) e o novo paralelo unnest()
(pág. 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;
<@
sendo o operador "elemento está contido por". Ligar:
SELECT f_upd_tbl('{"[2001-01-01,2001-01-05]"
,"[2001-01-20,2001-01-25]"}', '{s2,s5}');
Detalhes:
- Desaninhar vários arrays em paralelo