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

Có bất kỳ cú pháp thoát nào cho biến psql bên trong các hàm PostgreSQL không?

PSQL SET các biến không được nội suy bên trong các chuỗi được trích dẫn bằng đô la. Tôi không biết điều này chắc chắn, nhưng tôi nghĩ không có lối thoát hoặc thủ thuật nào khác để bật SET nội suy biến trong đó.

Người ta có thể nghĩ rằng bạn có thể nêm một :user chưa được trích dẫn giữa hai đoạn PL / pgSQL được báo giá bằng đô la để có được hiệu quả mong muốn. Nhưng điều này dường như không hiệu quả ... Tôi nghĩ rằng cú pháp yêu cầu một chuỗi đơn chứ không phải một chuỗi nối biểu thức. Có thể nhầm lẫn về điều đó.

Dù sao, điều đó không quan trọng. Có một cách tiếp cận khác (như Pasco đã lưu ý):viết thủ tục được lưu trữ để chấp nhận đối số PL / pgSQL. Đây là những gì nó sẽ trông như thế nào.

CREATE OR REPLACE FUNCTION foo("user" TEXT) RETURNS void AS
$$
BEGIN
        EXECUTE 'GRANT SELECT ON my_table TO GROUP ' || quote_ident(user);
END;    
$$ LANGUAGE plpgsql;

Lưu ý về chức năng này:

  1. EXECUTE tạo GRANT thích hợp trên mỗi lời gọi sử dụng đối số thủ tục của chúng tôi. Phần hướng dẫn sử dụng PG có tên " Thực thi lệnh động "giải thích EXECUTE chi tiết.
  2. Khai báo đối số thủ tục user phải được trích dẫn kép. Dấu ngoặc kép buộc nó phải được hiểu như một số nhận dạng.

Khi bạn xác định hàm như thế này, bạn có thể gọi nó bằng cách sử dụng các biến PSQL nội suy. Đây là một phác thảo.

  1. Chạy psql --variable user="'whoever'" --file=myscript.sql . Cần có một dấu ngoặc kép xung quanh tên người dùng!
  2. Trong myscript.sql, hãy xác định hàm như trên.
  3. Trong myscript.sql, đặt select foo(:user); . Đây là nơi chúng tôi dựa vào những dấu ngoặc kép đơn lẻ mà chúng tôi đặt vào giá trị của user .

Mặc dù điều này có vẻ hiệu quả, nhưng nó khiến tôi khá kinh ngạc. Tôi nghĩ SET các biến được dành cho cấu hình thời gian chạy. Mang theo dữ liệu trong SET có vẻ kỳ quặc.

Chỉnh sửa :đây là lý do cụ thể để không sử dụng SET biến. Từ manpage:"Các nhiệm vụ này được thực hiện trong giai đoạn khởi động rất sớm, vì vậy các biến dành riêng cho mục đích nội bộ có thể bị ghi đè sau này." Nếu Postgres quyết định sử dụng một biến có tên là user (hoặc bất cứ thứ gì bạn chọn), nó có thể ghi đè đối số tập lệnh của bạn bằng thứ gì đó mà bạn không bao giờ có ý định. Trên thực tế, psql đã lấy USER cho chính nó - điều này chỉ hoạt động vì SET phân biệt chữ hoa chữ thường. Điều này gần như đã phá vỡ mọi thứ ngay từ đầu!



  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 kết quả của một truy vấn động sử dụng câu lệnh chuẩn bị vào một bảng

  2. Giá trị duy nhất của PostgreSQL chiếm được nhiều cột

  3. Với Rails, làm cách nào để tôi có thể truy vấn db để biết số tổng hợp và được nhóm lại theo tuần?

  4. Khôi phục các bản ghi đã xóa trong PostgreSQL

  5. Làm cách nào tôi có thể chặn các sự kiện giao dịch JTA và nhận tham chiếu đến EntityManager hiện tại được liên kết với giao dịch