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:
-
EXECUTE
tạoGRANT
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íchEXECUTE
chi tiết. - 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.
- 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! - Trong myscript.sql, hãy xác định hàm như trên.
- 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ủauser
.
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!