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

Thực thi truy vấn bảng chéo động

Những gì bạn yêu cầu là không thể . SQL là một ngôn ngữ được đánh máy nghiêm ngặt. Các hàm PostgreSQL cần khai báo kiểu trả về (RETURNS .. ) vào thời điểm tạo .

Một cách hạn chế để giải quyết vấn đề này là với các hàm đa hình. Nếu bạn có thể cung cấp kiểu trả về tại thời điểm của hàm cuộc gọi . Nhưng điều đó không rõ ràng từ câu hỏi của 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

Bạn có thể trả về một kết quả hoàn toàn động với các bản ghi ẩn danh. Nhưng sau đó bạn được yêu cầu cung cấp danh sách định nghĩa cột với mọi cuộc gọi. Và làm thế nào để bạn biết về các cột được trả về? Bắt 22.

Có nhiều cách giải quyết khác nhau, tùy thuộc vào những gì bạn cần hoặc có thể làm việc với. Vì tất cả các cột dữ liệu của bạn dường như chia sẻ cùng một kiểu dữ liệu, tôi khuyên bạn nên trả về một mảng :text[] . Hoặc bạn có thể trả về một loại tài liệu như hstore hoặc json . Có liên quan:

  • Thay thế động cho trục xoay với CASE và GROUP BY

  • Tự động chuyển đổi các khóa hstore thành các cột cho một bộ khóa không xác định

Nhưng có thể đơn giản hơn nếu chỉ sử dụng hai lệnh gọi:1:Hãy để Postgres xây dựng truy vấn. 2:Thực thi và truy xuất các hàng đã trả về.

  • Chọn nhiều giá trị max () bằng một câu lệnh SQL duy nhất

Tôi sẽ không sử dụng chức năng từ Eric Minikel như đã trình bày trong câu hỏi của bạn hoàn toàn . Không an toàn khi chống lại việc đưa vào SQL bằng các mã nhận dạng có định dạng độc hại. Sử dụng format() để tạo chuỗi truy vấn trừ khi bạn đang chạy phiên bản lỗi thời cũ hơn Postgres 9.1.

Triển khai ngắn hơn và rõ ràng hơn có thể trông như thế này:

CREATE OR REPLACE FUNCTION xtab(_tbl regclass, _row text, _cat text
                              , _expr text  -- still vulnerable to SQL injection!
                              , _type regtype)
  RETURNS text AS
$func$
DECLARE
   _cat_list text;
   _col_list text;
BEGIN

-- generate categories for xtab param and col definition list    
EXECUTE format(
 $$SELECT string_agg(quote_literal(x.cat), '), (')
        , string_agg(quote_ident  (x.cat), %L)
   FROM  (SELECT DISTINCT %I AS cat FROM %s ORDER BY 1) x$$
 , ' ' || _type || ', ', _cat, _tbl)
INTO  _cat_list, _col_list;

-- generate query string
RETURN format(
'SELECT * FROM crosstab(
   $q$SELECT %I, %I, %s
      FROM   %I
      GROUP  BY 1, 2  -- only works if the 3rd column is an aggregate expression
      ORDER  BY 1, 2$q$
 , $c$VALUES (%5$s)$c$
   ) ct(%1$I text, %6$s %7$s)'
, _row, _cat, _expr  -- expr must be an aggregate expression!
, _tbl, _cat_list, _col_list, _type
);

END
$func$ LANGUAGE plpgsql;

Lệnh gọi hàm tương tự như phiên bản gốc của bạn. Hàm crosstab() được cung cấp bởi mô-đun bổ sung tablefunc mà phải được cài đặt. Khái niệm cơ bản:

  • Truy vấn bảng chéo PostgreSQL

Điều này xử lý các tên cột và bảng một cách an toàn. Lưu ý việc sử dụng các loại mã định danh đối tượng regclassregtype . Cũng hoạt động cho các tên đủ điều kiện giản đồ.

  • Tên bảng dưới dạng tham số hàm PostgreSQL

Tuy nhiên, nó không hoàn toàn an toàn trong khi bạn truyền một chuỗi sẽ được thực thi dưới dạng biểu thức (_expr - cellc trong truy vấn ban đầu của bạn). Loại đầu vào này vốn không an toàn trước SQL injection và không bao giờ nên được tiết lộ cho công chúng.

  • Chèn SQL vào các hàm Postgres so với các truy vấn đã chuẩn bị trước

Chỉ quét bảng một lần cho cả hai danh sách danh mục và sẽ nhanh hơn một chút.

Vẫn không thể trả về các loại hàng động hoàn toàn vì điều đó hoàn toàn không thể.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sửa chữa Postgresql sau khi nâng cấp lên OSX 10.7 Lion

  2. SQL LIKE điều kiện để kiểm tra số nguyên?

  3. Nhóm người dùng PostgreSQL NL

  4. Hủy một phiên / kết nối postgresql

  5. Làm cách nào để khôi phục dữ liệu từ vùng chứa Docker đã bị xóa? Làm thế nào để kết nối lại nó với dữ liệu?