Tôi phải thực hiện một vòng lặp trong cơ sở dữ liệu. Đây chỉ là yêu cầu một lần. Sau khi thực thi chức năng, tôi đang bỏ chức năng ngay bây giờ.
Có cách tiếp cận tốt nào để tạo các hàm tạm thời / dùng một lần không?
Câu trả lời:
Tôi cần biết cách sử dụng nhiều thời gian trong một kịch bản mà tôi đang viết. Hóa ra bạn có thể tạo một hàm tạm thời bằng lược đồ pg_temp. Đây là một lược đồ được tạo theo yêu cầu cho kết nối của bạn và là nơi các bảng tạm thời được lưu trữ. Khi kết nối của bạn bị đóng hoặc hết hạn, lược đồ này sẽ bị loại bỏ. Hóa ra nếu bạn tạo một hàm trên lược đồ này, thì lược đồ sẽ được tạo tự động. Vì thế,
create function pg_temp.testfunc() returns text as
$$ select 'hello'::text $$ language sql;
sẽ là một chức năng sẽ hoạt động miễn là kết nối của bạn còn tồn tại. Không cần gọi lệnh thả.
Một vài lưu ý bổ sung cho mẹo thông minh trong câu trả lời của @ crowmagnumb :
pg_temp
ở trong search_path
(như mặc định), theo Tom Lane để ngăn chặn ngựa thành Troy:CREATE FUNCTION pg_temp.f_inc(int)
RETURNS int AS 'SELECT $1 + 1' LANGUAGE sql IMMUTABLE;
SELECT pg_temp.f_inc(42);
f_inc
-----
43
Một hàm được tạo trong lược đồ tạm thời chỉ hiển thị trong cùng một phiên (giống như bảng tạm thời). Nó ẩn đối với tất cả các phiên khác (ngay cả đối với cùng một vai trò). Bạn có thể truy cập chức năng với vai trò khác trong cùng một phiên sau đó SET ROLE
.
Bạn thậm chí có thể tạo một chỉ mục chức năng dựa trên chức năng "tạm thời" này:
CREATE INDEX foo_idx ON tbl (pg_temp.f_inc(id));
Từ đó tạo ra một chỉ mục đơn giản bằng cách sử dụng một hàm tạm thời trên một bảng không tạm thời. Chỉ mục như vậy sẽ hiển thị cho tất cả các phiên nhưng vẫn chỉ hợp lệ cho phiên tạo. Người lập kế hoạch truy vấn sẽ không sử dụng chỉ mục chức năng, nơi biểu thức không được lặp lại trong truy vấn. Vẫn là một thủ thuật bẩn thỉu. Nó sẽ tự động bị loại bỏ khi phiên đóng cửa - như một đối tượng phụ thuộc. Cảm giác như thế này không được phép chút nào ...
Nếu bạn chỉ cần thực thi một hàm lặp đi lặp lại và tất cả những gì bạn cần là SQL, hãy xem xét một câu lệnh chuẩn bị thay thế. Nó hoạt động giống như một hàm SQL tạm thời bị chết vào cuối phiên. Tuy nhiên, không phải điều tương tự và chỉ có thể được sử dụng bởi chính nó EXECUTE
, không được lồng trong một truy vấn khác. Thí dụ:
PREPARE upd_tbl AS
UPDATE tbl t SET set_name = $2 WHERE tbl_id = $1;
Gọi:
EXECUTE upd_tbl(123, 'foo_name');
Chi tiết:
Nếu bạn đang sử dụng phiên bản 9.0, bạn có thể thực hiện việc này với câu lệnh DO mới:
http://www.postgresql.org/docs/current/static/sql-do.html
Với các phiên bản trước, bạn sẽ cần tạo hàm, gọi hàm và thả lại.
pg_temp.foo()
. Tôi không hiểu tại sao (!?) Hôm nay, 2014, với các ví dụ đơn giản và quá nhanh như Lua , ngôn ngữ SQL DML không thể cung cấp các hàm lambda (!).
DO
câu lệnh không được có tham số đầu vào và không thể trả về kết quả, ngược lại với các hàm.
Đối với các thủ tục quảng cáo, con trỏ không quá tệ. Tuy nhiên, chúng quá kém hiệu quả để sử dụng trong sản xuất.
Họ sẽ cho phép bạn dễ dàng lặp lại các kết quả sql trong db.