通过命令行将变量传递给 psql 文件。一个变量通过了另一个没有
Passing Variable in to psql file via command line. One variable passes other doesnt
我正在尝试通过命令行中的 psql 将两个变量传递到我 运行 的 .psql 文件中。我的一个变量转换为另一个不转换的值。 var1(靠近 where 子句的语句末尾的 id 值转换得很好,但 var2 作为 json 检查 id 的一部分的变量未转换。我认为这与我的方式有关逃避事情但玩了一个小时后我被困住了。谢谢
命令行
psql -h 127.0.0.1 -f "delete.psql" -v var1="$var1" -v var2="$var2"
delete.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')...
^
问题是 在 引用的字符串文字中不执行变量插值。所以这块不行:
'$ ? (@."id" <> (:'var2') )'
Variable interpolation will not be performed within quoted SQL literals and identifiers.
解决简单情况的一种方法是连接字符串。但是你的情况并不是那么简单,因为你真的想要一个 jsonpath
类型的参数,你可以很容易地为 SQL 注入空间...
jsonb_path_query_array()
有自己的方式在类型为 jsonb
的名为“vars”的第三个参数中传递变量。这是继续进行的安全方法。
或者 将 $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';
还删除了一些噪音括号。
相关:
- use \set variable inside plpgsql declare block
您正确地引用了变量。参见:
- How can I quote a named argument passed in to psql?
有多种替代方法:准备好的语句、(临时)函数...参见:
我正在尝试通过命令行中的 psql 将两个变量传递到我 运行 的 .psql 文件中。我的一个变量转换为另一个不转换的值。 var1(靠近 where 子句的语句末尾的 id 值转换得很好,但 var2 作为 json 检查 id 的一部分的变量未转换。我认为这与我的方式有关逃避事情但玩了一个小时后我被困住了。谢谢
命令行
psql -h 127.0.0.1 -f "delete.psql" -v var1="$var1" -v var2="$var2"
delete.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')...
^
问题是 在 引用的字符串文字中不执行变量插值。所以这块不行:
'$ ? (@."id" <> (:'var2') )'
Variable interpolation will not be performed within quoted SQL literals and identifiers.
解决简单情况的一种方法是连接字符串。但是你的情况并不是那么简单,因为你真的想要一个 jsonpath
类型的参数,你可以很容易地为 SQL 注入空间...
jsonb_path_query_array()
有自己的方式在类型为 jsonb
的名为“vars”的第三个参数中传递变量。这是继续进行的安全方法。
或者 将 $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';
还删除了一些噪音括号。
相关:
- use \set variable inside plpgsql declare block
您正确地引用了变量。参见:
- How can I quote a named argument passed in to psql?
有多种替代方法:准备好的语句、(临时)函数...参见: