首页 > 解决方案 > 通过命令行将变量传递给 psql 文件。一个变量通过其他不通过

问题描述

我正在尝试将两个变量传递给我从命令行通过 psql 运行的 .psql 文件。我的一个变量转换为另一个没有的值。var1(靠近 where 子句的语句末尾的 id 值被转换得很好,但是 var2 是 id 的 json 检查的一部分的变量没有被转换。我认为这与我如何逃避事情有关,但之后玩了一个小时我被卡住了。谢谢

命令行

psql -h 127.0.0.1 -f "delete.psql" -v var1="$var1" -v var2="$var2"

删除.sql

update data
   set value = jsonb_set(value, '{my_items}',
   jsonb_path_query_array(value->'item', '$ ? (@."id" <> (:'var2') )')) where id=(:'var1') ;

由于缺少 var2 转换而返回的错误

psql:delete.psql:3: ERROR:  syntax error at or near "var2"
LINE 3: ...th_query_array(value->'my_items', '$ ? (@."id" <> (:'var2')...
                                                                ^

标签: postgresqlpsql

解决方案


问题是变量插值不是带引号的字符串文字中执行的。所以这件作品不能工作:

'$ ? (@."id" <> (:'var2') )'

手册

变量插值不会在引用的 SQL 文字和标识符中执行。

解决简单情况的一种方法是连接字符串。但是您的情况并不是那么简单,因为您真的想要一个 type 的参数jsonpath,并且您可以轻松地为 SQL 注入引入空间......

jsonb_path_query_array()在名为“vars”类型的第三个参数中传递变量有自己的方式jsonb。这是继续进行的安全方法。

要么$var2作为合法jsonb文字传递,如: '{"var2" : "foo"}'. 那么您的UPDATE查询可以是:

update data set value = jsonb_set(value, '{my_items}', jsonb_path_query_array(value->'item', '$ ? (@."id" <> $var2)', :'var2')) where id = :'var1';

或者继续传递裸字符串值并让 Postgres 动态构造“vars”参数:jsonb_build_object('var2', :'var2'))

那么您的UPDATE查询可以是:

update data set value = jsonb_set(value, '{my_items}', jsonb_path_query_array(value->'item', '$ ? (@."id" <> $var2)', jsonb_build_object('var2', :'var2'))) where id = :'var1';

还删除了一些噪音括号。

有关的:

您正确引用了变量。看:

有多种替代方法:准备好的语句,(临时)函数......见:


推荐阅读