Chức năng vệ sinh
Những gì bạn hiện có có thể được đơn giản hóa / làm sạch thành:
CREATE OR REPLACE FUNCTION func_a (username text = '', databaseobject text = '')
RETURNS ????
LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY EXECUTE
format ('SELECT * FROM %s v1 LEFT JOIN %I v2 USING (id)'
, CASE WHEN username = '*' THEN 'view1' ELSE 'view3' END
, databaseobject);
END
$func$;
Bạn chỉ cần các phiên bản bổ sung của BEGIN ... END
trong phần thân hàm để bắt đầu các khối mã riêng biệt với phạm vi riêng của chúng, điều này hiếm khi cần thiết.
Toán tử nối SQL chuẩn là ||
. +
là một bổ sung "sáng tạo" của nhà cung cấp cũ của bạn.
Không sử dụng số nhận dạng caMeL-case trừ khi bạn trích dẫn kép chúng. Tốt nhất là không sử dụng chúng Xem:
- Tên cột PostgreSQL có phân biệt chữ hoa chữ thường không?
varchar(4000)
cũng được điều chỉnh cho phù hợp với một giới hạn cụ thể của SQL Server. Nó không có ý nghĩa cụ thể trong Postgres. Chỉ sử dụng varchar(4000)
nếu bạn thực sự cần giới hạn 4000 ký tự. Tôi chỉ sử dụng text
- ngoại trừ việc chúng tôi không cần bất kỳ biến nào ở tất cả tại đây, sau khi đơn giản hóa chức năng.
Nếu bạn chưa sử dụng format()
, tuy nhiên, hãy tham khảo hướng dẫn tại đây.
Loại trả lại
Bây giờ, đối với câu hỏi thực tế của bạn:Kiểu trả về cho một truy vấn động có thể phức tạp vì SQL yêu cầu điều đó phải được khai báo muộn nhất tại thời điểm gọi. Nếu bạn có bảng hoặc dạng xem hoặc kiểu kết hợp trong cơ sở dữ liệu của mình đã khớp với danh sách định nghĩa cột, bạn chỉ có thể sử dụng:
CREATE FUNCTION foo()
RETURNS SETOF my_view AS
...
Ngoài ra, đánh vần danh sách định nghĩa cột với RETURNS TABLE
(đơn giản nhất) :
CREATE FUNCTION foo()
RETURNS TABLE (col1 int, col2 text, ...) AS
...
Nếu bạn đang nhập hàng lên khi bạn tiếp tục, bạn có thể trả về các bản ghi ẩn danh:
CREATE FUNCTION foo()
RETURNS SETOF record AS
...
Nhưng sau đó bạn phải cung cấp danh sách định nghĩa cột cho mỗi lần gọi, vì vậy tôi hầu như không bao giờ sử dụng danh sách đó.
Tôi sẽ không sử dụng SELECT *
đầu tiên là. Sử dụng danh sách các cột cuối cùng để trả về và khai báo loại trả về của bạn cho phù hợp:
CREATE OR REPLACE FUNCTION func_a(username text = '', databaseobject text = '')
RETURNS TABLE(col1 int, col2 text, col3 date)
LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY EXECUTE
format ($f$SELECT v1.col1, v1.col2, v2.col3
FROM %s v1 LEFT JOIN %I v2 USING (id)$f$
, CASE WHEN username = '*' THEN 'view1' ELSE 'view3' END
, databaseobject);
END
$func$;
Đối với các truy vấn động hoàn toàn, hãy cân nhắc xây dựng truy vấn trong ứng dụng khách của bạn để bắt đầu, thay vì sử dụng một hàm.
Trước tiên, bạn cần hiểu những điều cơ bản:
- 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
- PL / pgSQL trong sổ tay Postgres
Sau đó, có nhiều tùy chọn nâng cao hơn với các kiểu đa hình, cho phép bạn chuyển kiểu trả về tại thời điểm gọi. Thông tin thêm trong chương cuối cùng của:
- 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