是否可以在postgresql中定义全局变量
Is it possible to define global variables in postgresql
我正在使用 postgresql 9.4,在编写函数时我想使用自定义 error_codes (int)。但是我可能想稍后更改确切的数值。
例如
-1 表示 USER_NOT_FOUND.
-2 表示 USER_DOES_NOT_HAVE_PERMISSION.
我可以在 table codes_table(code_name::text, code_value::integer) 中定义它们并在函数中使用它们,如下所示
(SELECT codes_table.code_value FROM codes_table WHERE codes_table.code_name = 'USER_NOT_FOUND')
还有其他方法吗?也许是全局变量?
Postgres 没有全局变量。
但是,您可以定义自定义配置参数。
为了清楚起见,使用给定的前缀定义您自己的参数,例如 glb
.
这个简单的函数将使在查询中放置参数变得更加容易:
create or replace function glb(code text)
returns integer language sql as $$
select current_setting('glb.' || code)::integer;
$$;
set glb.user_not_found to -1;
set glb.user_does_not_have_permission to -2;
select glb('user_not_found'), glb('user_does_not_have_permission');
用户定义的参数在会话中是本地的,因此应在每个会话开始时定义参数。
在 的基础上,有几种方法可以在当前会话之后保留配置参数。请注意,这些需要超级用户权限。
为特定数据库的所有连接设置一个值:
ALTER DATABASE db SET abc.xyz = 1;
您还可以使用 9.4 中添加的 ALTER SYSTEM
命令设置服务器范围的值。它似乎只适用于用户定义的参数,如果它们已经在您当前的会话中 SET
。另请注意,这需要重新加载配置才能生效。
SET abc.xyz = 1;
ALTER SYSTEM SET abc.xyz = 1;
SELECT pg_reload_conf();
9.4 之前的版本,您可以通过将参数添加到服务器的 postgresql.conf
文件来完成同样的事情。在 9.1 及更早版本中,您还需要注册一个 custom variable class.
您可以使用一个技巧并将您的变量声明为 1 行 CTE,然后将其与其余变量交叉连接。参见示例:
WITH
variables AS (
SELECT 'value1'::TEXT AS var1, 10::INT AS var2
)
SELECT t.*, v.*
FROM
my_table AS t
CROSS JOIN variables AS v
WHERE t.random_int_column = var2;
Postgresql 不支持数据库级别的全局变量。为什么不加:
CREATE TABLE global_variables (
key text not null PRIMARY KEY
value text
);
INSERT INTO global_variables (key, value) VALUES ('error_code_for_spaceship_engine', '404');
如果值的类型可能不同,请将 JSON 视为 value
的类型,但每种类型都需要反序列化代码。
你可以使用这个
CREATE OR REPLACE FUNCTION globals.maxCities()
RETURNS integer AS
$$SELECT 100 $$ LANGUAGE sql IMMUTABLE;
.. 直接在代码中使用globals.maxCities().
我正在使用 postgresql 9.4,在编写函数时我想使用自定义 error_codes (int)。但是我可能想稍后更改确切的数值。
例如
-1 表示 USER_NOT_FOUND.
-2 表示 USER_DOES_NOT_HAVE_PERMISSION.
我可以在 table codes_table(code_name::text, code_value::integer) 中定义它们并在函数中使用它们,如下所示
(SELECT codes_table.code_value FROM codes_table WHERE codes_table.code_name = 'USER_NOT_FOUND')
还有其他方法吗?也许是全局变量?
Postgres 没有全局变量。
但是,您可以定义自定义配置参数。
为了清楚起见,使用给定的前缀定义您自己的参数,例如 glb
.
这个简单的函数将使在查询中放置参数变得更加容易:
create or replace function glb(code text)
returns integer language sql as $$
select current_setting('glb.' || code)::integer;
$$;
set glb.user_not_found to -1;
set glb.user_does_not_have_permission to -2;
select glb('user_not_found'), glb('user_does_not_have_permission');
用户定义的参数在会话中是本地的,因此应在每个会话开始时定义参数。
在
为特定数据库的所有连接设置一个值:
ALTER DATABASE db SET abc.xyz = 1;
您还可以使用 9.4 中添加的 ALTER SYSTEM
命令设置服务器范围的值。它似乎只适用于用户定义的参数,如果它们已经在您当前的会话中 SET
。另请注意,这需要重新加载配置才能生效。
SET abc.xyz = 1;
ALTER SYSTEM SET abc.xyz = 1;
SELECT pg_reload_conf();
9.4 之前的版本,您可以通过将参数添加到服务器的 postgresql.conf
文件来完成同样的事情。在 9.1 及更早版本中,您还需要注册一个 custom variable class.
您可以使用一个技巧并将您的变量声明为 1 行 CTE,然后将其与其余变量交叉连接。参见示例:
WITH
variables AS (
SELECT 'value1'::TEXT AS var1, 10::INT AS var2
)
SELECT t.*, v.*
FROM
my_table AS t
CROSS JOIN variables AS v
WHERE t.random_int_column = var2;
Postgresql 不支持数据库级别的全局变量。为什么不加:
CREATE TABLE global_variables (
key text not null PRIMARY KEY
value text
);
INSERT INTO global_variables (key, value) VALUES ('error_code_for_spaceship_engine', '404');
如果值的类型可能不同,请将 JSON 视为 value
的类型,但每种类型都需要反序列化代码。
你可以使用这个
CREATE OR REPLACE FUNCTION globals.maxCities()
RETURNS integer AS
$$SELECT 100 $$ LANGUAGE sql IMMUTABLE;
.. 直接在代码中使用globals.maxCities().