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

Postgres làm ơn / pgsql LỖI:column column_name không tồn tại

Hàm của bạn có thể trông giống như sau:

CREATE FUNCTION select_transactions3(_col text, _val text, _limit int)    
  RETURNS SETOF transactions AS   
$BODY$   
BEGIN

RETURN QUERY EXECUTE '
   SELECT *
   FROM   transactions
   WHERE  ' || quote_ident(_col) || ' = $1
   LIMIT  $2'
USING _val, _limit;

END;   
$BODY$  
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;

TRONG PostgreSQL 9.1 trở lên đơn giản hơn với định dạng format()

...
RETURN QUERY EXECUTE format('
   SELECT *
   FROM   transactions
   WHERE  %I = $1
   LIMIT  $2', _col)
USING _val, _limit;
...

%I thoát khỏi các số nhận dạng như quote_ident() .

Những điểm chính:

  • Bạn đã gặp phải hạn chế của SQL động là bạn không thể sử dụng các tham số cho số nhận dạng. Bạn phải tạo chuỗi truy vấn với tên cột và sau đó thực thi nó.

  • Bạn có thể làm điều đó với các giá trị. Tôi chứng minh việc sử dụng USING mệnh đề cho EXECUTE . Cũng lưu ý việc sử dụng quote_ident() :ngăn chặn việc đưa vào SQL và một số lỗi cú pháp nhất định.

  • Tôi cũng đã đơn giản hóa phần lớn chức năng của bạn. [RETURN QUERY EXECUTE][3] làm cho mã của bạn ngắn hơn và nhanh hơn. Không cần lặp lại nếu tất cả những gì bạn làm là trả về hàng.

  • Tôi sử dụng IN có tên để bạn không bị nhầm lẫn với $ -notation trong chuỗi truy vấn. $1$2 bên trong chuỗi truy vấn đề cập đến các giá trị được cung cấp trong USING chứ không phải tham số đầu vào.

  • Tôi đổi thành SELECT * vì bạn vẫn phải trả lại toàn bộ hàng để khớp với kiểu trả về đã khai báo.

  • Cuối cùng nhưng không kém phần quan trọng:Hãy chắc chắn xem hướng dẫn sử dụng phải nói gì về các hàm được khai báo SECURITY DEFINER .

LOẠI TRỞ LẠI

Nếu bạn không muốn trả lại toàn bộ hàng, một khả năng thuận tiện là:

CREATE FUNCTION select_transactions3(_col text, _val text, _limit int)    
  RETURNS TABLE (invoice_no varchar(125), amount numeric(12,2) AS ...

Sau đó, bạn không phải cung cấp danh sách định nghĩa cột với mọi lệnh gọi và có thể đơn giản hóa thành:

SELECT * FROM select_to_transactions3('invoice_no', '1103300105472', 1);



  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 - INNER THAM GIA hai bảng với GIỚI HẠN

  2. Tại sao Postgres Cho phép Tôi Có các Cột không nằm trong Nhóm Theo?

  3. Cách chèn dòng mới trong PostgreSQL

  4. Làm cách nào để tạo chỉ mục trên trường JSON trong Postgres?

  5. Cách nhóm theo tháng trong PostgreSQL