当前位置: 首页 > 面试题库 >

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

房光临
2023-03-14
问题内容

我需要在查询之前设置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';

但它根本不会接受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;

由于我们没有运行任何动态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;

基于OP原始代码的测试

由于我们事先不知道mytable的架构,因此我们需要使用动态sql。我将set_config-
oneliner嵌入到get_sections()函数中,而不是使用通用的“ 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.


 类似资料:
  • 问题内容: 我想知道如何访问另一个函数中的一个函数。我看到了这样的代码: 那么,还有另一种方法来调用该 函数吗?我的第二个问题是,为什么在最后一行中我不打电话? 很好的解释深表感谢。 问题答案: 不,您不能直接调用它,因为它是的局部变量。 您需要使用,因为调用时返回了函数对象。要执行此功能对象,您需要 在这里您可以直接调用它,因为您可以访问它,因为它是由函数返回的。返回的对象实际上称为 闭包, 因

  • 问题内容: 我想从函数本身内部打印python函数的文档字符串。例如 目前,在定义之后,我将直接执行此操作。 但宁愿让函数自己执行此操作。 我已经尝试在my_function内调用它 ,但这没有用。 问题答案: 只要您不更改绑定到名称的对象,此方法就可以工作。 您会执行此操作的情况很少见,但确实会发生。 但是,如果您编写这样的装饰器: 现在您可以执行以下操作: 这将确保您的函数获得对自身的引用(类

  • 问题内容: 我刚刚开始自学Python,此脚本需要一些帮助: 我想得到它。 问题答案: 你快到了。您正在尝试修改全局变量,因此必须添加以下语句: 如果运行以下版本,则会看到您的版本中发生了什么: 输出: 运行它的方法,最终尝试在中修改函数的局部变量,这基本上是未定义的行为。请参阅文档中的警告: 注意: 默认 本地语言的 行为如以下功能所述:不应尝试对默认 本地 字典进行修改。如果需要在函数返回后查

  • 问题内容: 如果我有一个函数(在Python 2.5.2中)像这样: 我的问题是: 如何在 不 使用函数内部的 locals()的 情况下 从外部 获取 函数的局部变量(a,b)?(反射的种类) 是否可以从外部设置局部变量(例如 x ),以便注释行起作用?(我知道这听起来很奇怪)。 提前致谢。 编辑 : 每个人都在寻找用例。但这是一个奇怪的情况。(不要怪我,我没有创造出来)。这是场景: 我有一个包

  • 问题内容: 我的指令有 所以,我的问题是: 如何使用此指令将ng-disabled应用于元素? 问题答案: 您将设置一个范围变量,例如: 然后在指令中可以设置该变量:

  • 我在看H.J.Lu的补丁:更新x86 rdrand intrinsics。我不知道我是否应该使用rdrand\u64、rdrand64\u步骤,或者是否有其他功能。似乎没有为他们编写测试用例。 似乎也缺乏手册页(来自Ubuntu 14,GCC 4.8.4): 如何使用RDRAND内部函数来生成一个32字节的块? 一个相关的问题是RDRAND和RDSEED内部函数GCC和Intel C。但它没有告诉