gpt4 book ai didi

sql - PostgreSQL:如何从函数内部设置 search_path?

转载 作者:行者123 更新时间:2023-11-29 11:45:35 29 4
gpt4 key购买 nike

我需要在查询之前设置搜索路径。新的搜索路径应该基于函数参数。我到底该怎么做?现在我有:

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';

但它根本不会接受 $1。我也尝试过使用 quote_ident($1) 但它没有用。

谢谢!

最佳答案

通用的解决方案

我使用 set_config() 创建了一个纯 sql 函数。

此解决方案支持在逗号分隔的字符串中设置多个架构。默认情况下更改适用于当前 session 。将“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;

因为我们没有运行任何动态 sql,所以 sql 注入(inject)的机会应该更少。只是为了确保我通过删除除字母数字、空格和逗号之外的所有字符来对文本进行一些简单的清理。转义/引用字符串并非易事,但我不是专家,所以.. =)

请记住,如果您设置格式错误的路径,则不会有任何反馈。

下面是一些用于测试的示例代码:

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;

基于OP原代码的测试

由于事先不知道mytable的schema,所以需要使用动态sql。我将 set_config-oneliner 嵌入到 get_sections() 函数中,而不是使用通用的函数。

注意:我必须在 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.

关于sql - PostgreSQL:如何从函数内部设置 search_path?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21259551/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com