Thiết lập sạch:
CREATE TABLE tbl (
given_date date
, set_name varchar
);
Sử dụng một thuật ngữ số ít làm tên cột cho một đĩa đơn giá trị.
Kiểu dữ liệu rõ ràng là date
và không phải là timestamp
.
Để chuyển đổi các tham số văn bản của bạn thành một bảng hữu ích:
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" là tiện dụng nhưng có những lưu ý của nó. Postgres 9.4 thêm một giải pháp sạch, Postgres 10 cuối cùng đã làm sạch các hành vi của điều này. Xem bên dưới.
Thực thi động
Tuyên bố chuẩn bị sẵn
Các câu lệnh chuẩn bị chỉ hiển thị với phiên tạo và kết thúc với nó. Theo tài liệu:
Các câu lệnh chuẩn bị chỉ tồn tại trong khoảng thời gian của phiên cơ sở dữ liệu hiện tại.
PREPARE
một lần mỗi phiên :
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;
Hoặc sử dụng các công cụ do khách hàng của bạn cung cấp để chuẩn bị câu lệnh.
Thực hiện n lần với các tham số tùy ý:
EXECUTE upd_tbl('2001-01-01to2001-01-05,2001-01-10to2001-01-15', 's1,s4');
Chức năng phía máy chủ
Các chức năng vẫn tồn tại và hiển thị cho tất cả phiên.
CREATE FUNCTION
một lần :
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;
Gọi n lần:
SELECT f_upd_tbl('2001-01-01to2001-01-05,2001-01-20to2001-01-25', 's2,s5');
SQL Fiddle
Thiết kế cao cấp
Sử dụng tham số mảng (vẫn có thể được cung cấp dưới dạng chuỗi ký tự), daterange
gõ (cả pg 9.3) và song song mới unnest()
(trang 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;
<@
là toán tử "phần tử được chứa bởi".
Gọi:
SELECT f_upd_tbl('{"[2001-01-01,2001-01-05]"
,"[2001-01-20,2001-01-25]"}', '{s2,s5}');
Chi tiết:
- Bỏ kết hợp nhiều mảng song song