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

PostgreSQL:làm cách nào để đặt search_path từ bên trong một hàm?

Giải pháp chung

Tôi đã tạo một hàm sql thuần túy bằng cách sử dụng set_config ().

Giải pháp này hỗ trợ thiết lập nhiều lược đồ trong một chuỗi được phân tách bằng dấu phẩy. Theo mặc định, thay đổi áp dụng cho phiên hiện tại. Đặt thông số "is_local" thành true sẽ làm cho thay đổi chỉ áp dụng cho giao dịch hiện tại, xem http://www.postgresql.org/docs/9.4/static/functions-admin.html để biết thêm chi tiết.

CREATE OR REPLACE FUNCTION public.set_search_path(path TEXT, is_local BOOLEAN DEFAULT false) RETURNS TEXT AS $$
    SELECT set_config('search_path', regexp_replace(path, '[^\w ,]', '', 'g'), is_local);
$$ LANGUAGE sql;

Vì chúng tôi không chạy bất kỳ sql động nào nên ít có khả năng bị tiêm sql hơn. Chỉ để chắc chắn rằng tôi đã thêm một số cách làm sạch văn bản bằng cách xóa tất cả các ký tự ngoại trừ chữ và số, dấu cách và dấu phẩy. Thoát / trích dẫn chuỗi không phải là tầm thường, nhưng tôi không phải là một chuyên gia, vì vậy .. =)

Hãy nhớ rằng sẽ không có phản hồi nếu bạn đặt một đường dẫn không đúng định dạng.

Đây là một số mã mẫu để thử nghiệm:

DROP SCHEMA IF EXISTS testschema CASCADE;
CREATE SCHEMA testschema;
CREATE TABLE testschema.mytable ( id INTEGER );

SELECT set_search_path('testschema, public');
SHOW search_path;

INSERT INTO mytable VALUES(123);
SELECT * FROM mytable;

Một bài kiểm tra dựa trên mã gốc của OP

Vì chúng ta không biết trước lược đồ cho mytable, chúng ta cần sử dụng dynamic sql. Tôi đã nhúng set_config-oneliner vào hàm get_section () - thay vì sử dụng hàm chung chung.

Lưu ý: Tôi đã phải đặt is_local =false trong set_config () để điều này hoạt động. Điều đó có nghĩa là đường dẫn đã sửa đổi vẫn còn sau khi chạy hàm. Tôi không chắc tại sao.

DROP SCHEMA IF EXISTS testschema CASCADE;
CREATE SCHEMA testschema;
SET search_path TO public;

CREATE TABLE testschema.mytable ( id INTEGER, name varchar, type varchar );
INSERT INTO testschema.mytable VALUES (123,'name', 'some-type');
INSERT INTO testschema.mytable VALUES (567,'name2', 'beer');

CREATE OR REPLACE FUNCTION get_sections(schema_name TEXT) RETURNS 
TABLE(id integer, name varchar, type varchar) AS $$
BEGIN
    PERFORM set_config('search_path', regexp_replace(schema_name||', public', '[^\w ,]', '', 'g'), true);
    EXECUTE 'SELECT id, name, type FROM mytable';
END;
$$ LANGUAGE plpgsql;

SET search_path TO public;
SELECT * FROM get_sections('testschema');
SHOW search_path;  -- Unfortunately this has modified the search_path for the whole session.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nén văn bản trong PostgreSQL

  2. TypeError:create () có nhiều giá trị cho đối số từ khóa 'context'

  3. Các phương pháp hay nhất về bảo mật PostgreSQL

  4. Thay đổi / đặt lại mật khẩu người dùng postgresql trên Windows 7

  5. Trong psql làm thế nào để chạy một Vòng lặp cho một truy vấn Chọn với CTE và nhận kết quả hiển thị nếu tôi chạy nó trong một db chỉ đọc?