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

PostgreSQL - Viết sql động trong thủ tục được lưu trữ trả về tập kết quả

Có chỗ cho những cải tiến:

CREATE OR REPLACE FUNCTION report_get_countries_new (starts_with text
                                                   , ends_with   text = NULL)
  RETURNS SETOF lookups.countries AS
$func$
DECLARE
   sql text := 'SELECT * FROM lookups.countries WHERE country_name >= $1';
BEGIN
   IF ends_with IS NOT NULL THEN
      sql := sql || ' AND country_name <= $2';
   END IF;

   RETURN QUERY EXECUTE sql
   USING starts_with, ends_with;
END
$func$ LANGUAGE plpgsql;
-- the rest is default settings

Những điểm chính

  • PostgreSQL 8.4 đã giới thiệu USING mệnh đề cho EXECUTE , điều này hữu ích vì một số lý do. Tóm tắt lại trong sách hướng dẫn:

    Chuỗi lệnh có thể sử dụng các giá trị tham số, được tham chiếu trong lệnh dưới dạng $1, $2 , v.v. Các ký hiệu này đề cập đến các giá trị được cung cấp trong USING mệnh đề. Phương pháp này thường thích hợp hơn khi chèn các datavalues ​​vào chuỗi lệnh dưới dạng văn bản:nó tránh được việc chuyển đổi các giá trị thành văn bản và ngược lại trong thời gian chạy và nó ít bị tấn công SQL-injection hơn nhiều vì không cần trích dẫn hoặc thoát.

    IOW, nó an toàn và nhanh hơn so với việc xây dựng một chuỗi truy vấn với biểu diễn văn bản của các tham số, ngay cả khi được làm sạch bằng quote_literal() .
    Lưu ý rằng $1, $2 trong chuỗi truy vấn, hãy tham chiếu đến các giá trị được cung cấp trong USING mệnh đề, không vào các tham số chức năng.

  • Trong khi bạn trả về SELECT * FROM lookups.countries , bạn có thể đơn giản hóa RETURN khai báo như đã chứng minh:

    RETURNS SETOF lookups.countries
    

    Trong PostgreSQL, có một kiểu kết hợp được xác định tự động cho mọi bảng. Sử dụng nó. Hiệu quả là chức năng phụ thuộc vào loại và bạn sẽ nhận được thông báo lỗi nếu bạn cố gắng thay đổi bảng. Bỏ và tạo lại hàm trong trường hợp như vậy.

    Điều này có thể mong muốn hoặc không - nói chung là như vậy! Bạn muốn được thông báo về các tác dụng phụ nếu bạn thay đổi bảng. Theo cách bạn có, hàm của bạn sẽ bị hỏng một cách im lặng và tạo ra một ngoại lệ trong lần gọi tiếp theo.

  • Nếu bạn cung cấp mặc định rõ ràng đối với tham số thứ hai trong khai báo như đã trình bày, bạn có thể (nhưng không cần phải) đơn giản hóa lệnh gọi trong trường hợp bạn không muốn đặt giới hạn trên với ends_with .

    SELECT * FROM report_get_countries_new('Zaire');
    

    thay vì:

    SELECT * FROM report_get_countries_new('Zaire', NULL);
    

    Hãy lưu ý về việc quá tải hàm trong ngữ cảnh này.

  • Không trích dẫn tên ngôn ngữ 'plpgsql' ngay cả khi điều đó được chấp nhận (hiện tại). Đó là một số nhận dạng.

  • Bạn có thể gán một biến tại thời điểm khai báo. Tiết kiệm thêm một bước.

  • Các tham số được đặt tên trong tiêu đề. Bỏ những dòng vô nghĩa:

     starts_with ALIAS FOR $1;
     ends_with ALIAS FOR $2;
    


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL ngược LIKE

  2. Tại sao Postgres nói rằng cột không tồn tại?

  3. Tạo chế độ chờ lạnh cho PostgreSQL bằng Amazon AWS

  4. mở mảng postgresql thành các hàng

  5. Cách Width_Bucket () hoạt động trong PostgreSQL