postgresql - postgresql:可能的临时json变量?
问题描述
如何创建一个可以引用的临时/非常短暂的 json 对象(用于在 RLS 策略中构建检查)?稍后将使用“真实”json 对象作为会话变量调用这些策略,我只是在运行时之前无法访问这些值,并且我无法控制这一点。
我在考虑 SET LOCAL,但看起来你不能使用 json 类型?我可以伪造一个 json 类型吗?例如我试过:
SET LOCAL myjson '{"foo":123, "color":red}';
SELECT myjson ->> 'foo';
但我得到一个语法错误:
ERROR: syntax error at or near "'{"foo":123, "color":red}'"
LINE 1: SET LOCAL myjson '{"foo":123, "color":red}';
^
SQL state: 42601
Character: 18
解决方案
根据您是否需要确切的SELECT myjson ->> 'foo';
语法,有几个选项。我只介绍几个:
如果需要SELECT myjson ->> 'foo';
,我能想到的最接近的是创建一个返回 json 的函数:
edb=# CREATE OR REPLACE FUNCTION myjson() RETURNS json AS $$ BEGIN RETURN '{"foo":"123", "color":"red"}'::json; END; $$ LANGUAGE plpgsql;
CREATE FUNCTION
edb=# SELECT myjson ->> 'foo';
?column?
----------
123
(1 row)
如果您负担得起使用 CTE,您可以这样做:
edb=# WITH x AS (SELECT '{"foo":"123", "color":"red"}'::json AS myjson)
SELECT myjson ->> 'foo' FROM x;
?column?
----------
123
(1 row)
你甚至可以放入myjson
一个临时表:
edb=# SELECT '{"foo":"123", "color":"red"}'::json AS myjson INTO TEMPORARY TABLE temptable;
SELECT 1
edb=# SELECT myjson->>'foo' FROM temptable;
?column?
----------
123
(1 row)
如果你想使用SET LOCAL
,你会遇到一些问题:
- 需要在一个事务块中(即
BEGIN/COMMIT/ROLLBACK
) - 需要以各种命名空间为前缀(任何名称都可以)
- 您不能将
SELECT
其视为会话中浮动的变量,您需要使用current_setting()
- 您需要在检索它后将其转换为
current_setting()
(换句话说,您必须将其存储为文本,而不是 json)
一个工作示例是这样的:
edb=# SET LOCAL myjson = '{"foo":"123", "color":"red"}';
WARNING: SET LOCAL can only be used in transaction blocks
ERROR: unrecognized configuration parameter "myjson"
edb=# SET LOCAL myparam.myjson = '{"foo":"123", "color":"red"}';
WARNING: SET LOCAL can only be used in transaction blocks
SET
edb=# BEGIN;
BEGIN
edb=# SET LOCAL myparam.myjson = '{"foo":"123", "color":"red"}';
SET
edb=# SELECT current_setting('myparam.myjson');
current_setting
------------------------------
{"foo":"123", "color":"red"}
(1 row)
edb=# SELECT current_setting('myparam.myjson')::json ->> 'foo';
?column?
----------
123
(1 row)
如果您想使用SET
但不想使用BEGIN/COMMIT
块,请尝试使用SET SESSION
(或仅使用 plain SET
)。您仍然需要将其放入命名空间(即foo.myjson
)并用于current_setting(foo.myjson)
提取它。
推荐阅读
- java - 在 NetBeans 8.2 IDE 开发程序中使用 javamail 将 3 个文件发送给收件人
- mysql - Xampp安装和.frm文件上的Mysql致命错误
- android - 在 Fragments Kotlin Android Studio 中上下文这个问题
- emacs - emacs 不突出显示 Scheme .sls 文件
- javascript - 根据键入命令的人,机器人将如何显示不同的消息
- python - 如何有效地使用 input().split() 在一行中从用户那里获取至少 2 个输入?
- haskell - 将类型与 exceptT IO monad 转换器对齐
- ubuntu - WslRegisterDistribution 失败并出现错误:0x80070241 Windows 无法验证此文件的数字签名
- javascript - 在 setState 更改 React Native 时使用负载指示器
- php - 如何访问此数组中的值