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

Thực thi động các truy vấn trong PL / pgSQL

Thống kê hệ thống

Trước khi tự triển khai, hãy xem bảng hệ thống pg_statistic hoặc chế độ xem pg_stats :

Nó có thể đã có một số thống kê mà bạn sắp tính toán. Nó được điền bởi ANALYZE , vì vậy bạn có thể chạy nó cho các bảng mới (hoặc bất kỳ) trước khi kiểm tra.

-- ANALYZE tbl;  -- optionally, to init / refresh
SELECT * FROM pg_stats
WHERE tablename = 'tbl'
AND   schemaname = 'public';

Hàm plpgsql động chung

Bạn muốn trả về giá trị tối thiểu cho mọi cột trong một bảng nhất định . Đây không phải là một nhiệm vụ tầm thường, bởi vì một hàm (như SQL nói chung) yêu cầu biết kiểu trả về tại thời điểm tạo - hoặc ít nhất là tại thời điểm gọi với sự trợ giúp của các kiểu dữ liệu đa hình.

Chức năng này thực hiện mọi thứ tự động và an toàn. Hoạt động cho bất kỳ bảng, miễn là hàm tổng hợp min() được phép cho mọi cột. Nhưng bạn cần để biết cách của bạn xung quanh PL / pgSQL.

CREATE OR REPLACE FUNCTION f_min_of(_tbl anyelement)
  RETURNS SETOF anyelement
  LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY EXECUTE (
   SELECT format('SELECT (t::%2$s).* FROM (SELECT min(%1$s) FROM %2$s) t'
                , string_agg(quote_ident(attname), '), min(' ORDER BY attnum)
                , pg_typeof(_tbl)::text)
   FROM   pg_attribute
   WHERE  attrelid = pg_typeof(_tbl)::text::regclass
   AND    NOT attisdropped  -- no dropped (dead) columns
   AND    attnum > 0        -- no system columns
   );
END
$func$;

Gọi (quan trọng!):

SELECT * FROM f_min_of(NULL::tbl);  -- tbl being the table name

db <> fiddle tại đây
sqlfiddle

Bạn cần hiểu những khái niệm sau:

  • SQL động trong plpgsql với EXECUTE
  • Các kiểu đa hình
  • Loại hàng và loại bảng trong Postgres
  • Cách bảo vệ khỏi việc đưa vào SQL
  • Các hàm tổng hợp
  • Danh mục hệ thống

Câu trả lời liên quan với giải thích chi tiết:

Khó khăn đặc biệt với kiểu không khớp

Tôi đang tận dụng Postgres để xác định loại hàng cho mọi bảng hiện có. Sử dụng khái niệm về các kiểu đa hình, tôi có thể tạo một hàm hoạt động cho bất kỳ bảng nào.

Tuy nhiên, một số hàm tổng hợp trả về kiểu dữ liệu có liên quan nhưng khác so với cột bên dưới. Ví dụ:min(varchar_column) trả về text , tương thích với bit, nhưng không chính xác cùng một kiểu dữ liệu. Các hàm PL / pgSQL có một điểm yếu ở đây và nhấn mạnh vào các kiểu dữ liệu chính xác như được khai báo trong RETURNS mệnh đề. Không cố gắng truyền, thậm chí không truyền ẩn, không nói về nhiệm vụ chuyển nhượng.

Điều đó cần được cải thiện. Đã kiểm tra với Postgres 9.3. Không kiểm tra lại với 9.4, nhưng tôi khá chắc chắn, không có gì thay đổi trong lĩnh vực này.

Đó là nơi mà cấu trúc này xuất hiện dưới dạng giải pháp thay thế :

SELECT (t::tbl).* FROM (SELECT ... FROM tbl) t;

Bằng cách truyền toàn bộ hàng sang kiểu hàng của bảng bên dưới một cách rõ ràng, chúng tôi buộc các phép gán để nhận được kiểu dữ liệu ban đầu cho mọi cột.

Điều này có thể không thành công đối với một số chức năng tổng hợp. sum() trả về numeric cho một sum(bigint_column) để chứa một tổng làm tràn kiểu dữ liệu cơ sở. Truyền trở lại bigint có thể thất bại ...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lưu trữ dữ liệu được mã hóa trong Postgres

  2. PostgreSQL:ST_GeomFromText (không xác định) không tồn tại

  3. LIKE với% trên tên cột

  4. Thứ tự Laravel của phần mềm trung gian (Middleware Priority). Nhiều người thuê sử dụng Postgres

  5. Di chuyển Django 1.8 không thể truyền id cột thành số nguyên