Penyiapan bersih:
CREATE TABLE tbl (
given_date date
, set_name varchar
);
Gunakan istilah tunggal sebagai nama kolom untuk tunggal value.
Tipe datanya jelas date
dan bukan timestamp
.
Untuk mengubah parameter teks Anda menjadi tabel yang berguna:
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;
"Paralel unnest" berguna tetapi memiliki peringatan. Postgres 9.4 menambahkan solusi bersih, Postgres 10 akhirnya membersihkan perilaku ini. Lihat di bawah.
Eksekusi dinamis
Pernyataan yang disiapkan
Pernyataan yang disiapkan hanya dapat dilihat oleh sesi pembuatan dan mati bersamanya. Per dokumentasi:
Pernyataan yang disiapkan hanya bertahan selama sesi database saat ini.
PREPARE
sekali per sesi :
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;
Atau gunakan alat yang disediakan oleh klien Anda untuk menyiapkan pernyataan.
Jalankan n kali dengan parameter arbitrer:
EXECUTE upd_tbl('2001-01-01to2001-01-05,2001-01-10to2001-01-15', 's1,s4');
Fungsi sisi server
Fungsi dipertahankan dan terlihat oleh semua sesi.
CREATE FUNCTION
sekali :
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;
Telepon n kali:
SELECT f_upd_tbl('2001-01-01to2001-01-05,2001-01-20to2001-01-25', 's2,s5');
SQL Fiddle
Desain unggul
Gunakan parameter larik (masih dapat diberikan sebagai literal string), daterange
ketik (keduanya hal 9.3) dan paralel baru unnest()
(hal 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;
<@
menjadi operator "elemen dikandung oleh".
Telepon:
SELECT f_upd_tbl('{"[2001-01-01,2001-01-05]"
,"[2001-01-20,2001-01-25]"}', '{s2,s5}');
Detail:
- Hapus beberapa array secara paralel