我需要在查询之前设置 search_path。新的搜索路径应基于函数参数。我该怎么做?现在我有:
CREATE FUNCTION get_sections(integer) RETURNS
table(id integer, name varchar, type varchar) as $$
SET search_path to $1, public;
select id, name, type from sections;
$$ language 'sql';
Run Code Online (Sandbox Code Playgroud)
但它根本不接受 1 美元。我也尝试过 quote_ident($1) 但它没有用。
谢谢!
我使用 set_config() 创建了一个纯 sql 函数。
此解决方案支持在逗号分隔的字符串中设置多个模式。默认情况下,更改适用于当前会话。将“is_local”参数设置为 true 会使更改仅适用于当前事务,有关详细信息,请参阅http://www.postgresql.org/docs/9.4/static/functions-admin.html。
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;
Run Code Online (Sandbox Code Playgroud)
由于我们没有运行任何动态 sql,因此 sql 注入的机会应该更少。为了确保我通过删除除字母数字、空格和逗号以外的所有字符,对文本进行了一些简单的清理。转义/引用字符串并非易事,但我不是专家,所以.. =)
请记住,如果您设置了格式错误的路径,则不会有任何反馈。
下面是一些用于测试的示例代码:
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;
Run Code Online (Sandbox Code Playgroud)
由于我们事先不知道mytable的schema,所以需要使用动态sql。我将 set_config-oneliner 嵌入到 get_sections() 函数中,而不是使用 generic'ish 函数。
注意:我必须在 set_config() 中设置 is_local=false 才能使其工作。这意味着修改后的路径在函数运行后仍然存在。我不知道为什么。
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.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8453 次 |
| 最近记录: |