Nó có thể hoạt động như thế này:
CREATE OR REPLACE FUNCTION tt_query(orig_name regclass, data_tt timestamp)
RETURNS SETOF record AS
$func$
BEGIN
EXECUTE 'CREATE OR REPLACE TEMP VIEW tmp as
select *
from '
|| orig_name
|| ' where trigger_changed >'
|| quote_literal(data_tt)
|| ' ORDER BY trigger_changed DESC';
-- other work on view tmp
-- return the rows of view temp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
-
Lưu ý việc sử dụng loại mã nhận dạng đối tượng
regclass
để tự động tránh việc đưa vào SQL. -
Không sử dụng cú pháp lỗi thời
var ALIAS for $1
nếu bạn không cần phải làm vậy. Khai báo tên tham số thay thế. -
Tôi sẽ không sử dụng từ khóa
temp
làm định danh, ngay cả khi điều đó được cho phép. Sử dụngtmp
thay vào đó. -
Sử dụng
RETURN QUERY
để trả về một tập hợp các bản ghi. Đây thậm chí có thể là một cuộc gọi tĩnh mà không cóEXECUTE
. Tuy nhiên, bạn đang trả lại hồ sơ ẩn danh và Postgres yêu cầu danh sách định nghĩa cột với mọi cuộc gọi:
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
Điều này khá khó sử dụng.
Các giải pháp tốt hơn
Nếu bạn biết kiểu trả về (ngay cả khi tên bảng đang thay đổi, danh sách các cột có thể chia sẻ cùng kiểu), hãy khai báo nó tại thời điểm tạo. Hãy xem xét câu hỏi có liên quan này:
PostgreSQL:ERROR:42601:cần có danh sách định nghĩa cột cho các hàm trả về" bản ghi "
Nếu loại trả lại khác nhau với tên bảng được cung cấp, vẫn còn một giải pháp tốt hơn nhiều. Vì bạn đang tạo chế độ xem với SELECT * FROM tbl
, bạn có thể sử dụng loại bảng nổi tiếng là đa hình
tham số:
CREATE OR REPLACE FUNCTION tt_query(orig_name anyelement, data_tt timestamp)
RETURNS SETOF anyelement AS
$func$
BEGIN
EXECUTE format('CREATE OR REPLACE TEMP VIEW tmp AS
SELECT * FROM %s
WHERE trigger_changed > %L
ORDER BY trigger_changed DESC'
,pg_typeof(orig_name)
,data_tt);
-- other work on view tmp
-- return the rows of view tmp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
Cuộc gọi đơn giản hóa:
SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
Đồng thời sử dụng format()
để nối chuỗi an toàn và đơn giản.
Thêm chi tiết trong câu trả lời có liên quan này:
Cấu trúc lại một hàm PL / pgSQL để trả về kết quả đầu ra của các truy vấn SELECT khác nhau