在存储过程中设置自定义选项

Setting a customized option in a stored procedure

我试图在存储过程中设置自定义选项,但它存储的是变量名而不是变量的内容。

CREATE OR REPLACE FUNCTION set_user(_user_id bigint, is_local boolean default true) returns void AS $$
BEGIN
  SET my.user_id TO _user_id;
END;
$$ LANGUAGE PLPGSQL;

select set_user(1);
select current_setting('my.user_id');
 current_setting 
-----------------
 _user_id   
(1 row)

我期望 current_setting 到 return 1,而不是字符串值 "_user_id"

第一个解决方案

SET 的语法是:

SET [ SESSION | LOCAL ] configuration_parameter { TO | = } { value |'value' | DEFAULT }

其中 value 是给定 configuration_parameter 的新值。

为了分配存储在 _user_id 变量中的值,您需要生成一个动态命令,然后 EXECUTE 它。

这就是这样做的方法:

CREATE OR REPLACE FUNCTION set_user(_user_id bigint, is_local boolean default true) 
RETURNS void 
LANGUAGE PLPGSQL
AS $$
BEGIN
  EXECUTE 'SET my.user_id TO ' || quote_nullable(_user_id);
END;
$$;

附加 SQL Fiddle link 用于测试目的。

注:

    如果输入参数为空,
  • quote_nullable() 函数将 return NULL。在您的情况下可能没有必要。

第二种解决方案

您也可以使用 set_config() 函数实现与@a_horse_with_no_name 所述相同的效果。您的函数将如下所示:

CREATE OR REPLACE FUNCTION set_user(_user_id bigint, is_local boolean default true) 
RETURNS void 
LANGUAGE PLPGSQL
AS $$
BEGIN
  PERFORM set_config('my.user_id', _user_id::TEXT, false);
END;
$$;

附加 SQL Fiddle link 用于测试目的。

注:

  • 您必须明确地将第二个参数转换为 varchar 类型
  • PERFORM 用于评估表达式并丢弃结果,因为它不需要
  • 你也可以在这里使用 quote_nullable() 函数