PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Trả về các hàng SETOF từ hàm PostgreSQL

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách đặt thời gian chờ câu lệnh để thực hiện truy vấn

  2. Làm cách nào để tôi có thể Chèn đối tượng JSON vào Postgres bằng Java readyStatement?

  3. Quy ước đặt tên PostgreSQL

  4. Tạo trình kích hoạt để chèn bảng con trả về lỗi khó hiểu

  5. phần trăm từ dữ liệu biểu đồ