单个 postgresql 查询中的文本和 jsonb 连接
Text and jsonb concatenation in a single postgresql query
如何在 postgresql 中连接一个连接的 jsonb 对象中的字符串?换句话说,我在同一个查询中同时使用了 JSONb 连接运算符和文本连接运算符,运行 遇到了麻烦。
或者...如果我应该执行一个完全不同的查询,我将不胜感激听到建议。目标是更新包含 jsonb 列的行。我们不想覆盖查询中未提供的 jsonb 列中的现有键值对,我们还想一次更新多行。
我的查询:
update contacts as c set data = data || '{"geomatch": "MATCH","latitude":'||v.latitude||'}'
from (values (16247746,40.814140),
(16247747,20.900840),
(16247748,20.890570)) as v(contact_id,latitude) where c.contact_id = v.contact_id
错误:
ERROR: invalid input syntax for type json
LINE 85: update contacts as c set data = data || '{"geomatch": "MATCH...
^
DETAIL: The input string ended unexpectedly.
CONTEXT: JSON data, line 1: {"geomatch": "MATCH","latitude":
SQL state: 22P02
Character: 4573
您可能正在寻找
SET data = data || ('{"geomatch": "MATCH","latitude":'||v.latitude||'}')::jsonb
-- ^^ jsonb ^^ text ^^ text
但这不是构建 JSON 对象的方式 - v.latitude
可能不是有效的 JSON 文字,甚至包含一些像 "", "otherKey": "oops"
这样的注入。 (不可否认,在您的示例中,您可以控制这些值,它们是数字,因此可能没问题,但这仍然是一种不好的做法)。相反,使用 jsonb_build_object
:
SET data = data || jsonb_build_object('geomatch', 'MATCH', 'latitude', v.latitude)
有两个问题。第一个是运算符优先级,防止将 jsonb
对象连接到读取的 text
对象。第二个是 text
部分的串联需要转换为 jsonb
.
这应该有效:
update contacts as c
set data = data || ('{"geomatch": "MATCH","latitude":'||v.latitude||'}')::jsonb
from (values (16247746,40.814140),
(16247747,20.900840),
(16247748,20.890570)) as v(contact_id,latitude)
where c.contact_id = v.contact_id
;
如何在 postgresql 中连接一个连接的 jsonb 对象中的字符串?换句话说,我在同一个查询中同时使用了 JSONb 连接运算符和文本连接运算符,运行 遇到了麻烦。
或者...如果我应该执行一个完全不同的查询,我将不胜感激听到建议。目标是更新包含 jsonb 列的行。我们不想覆盖查询中未提供的 jsonb 列中的现有键值对,我们还想一次更新多行。
我的查询:
update contacts as c set data = data || '{"geomatch": "MATCH","latitude":'||v.latitude||'}'
from (values (16247746,40.814140),
(16247747,20.900840),
(16247748,20.890570)) as v(contact_id,latitude) where c.contact_id = v.contact_id
错误:
ERROR: invalid input syntax for type json
LINE 85: update contacts as c set data = data || '{"geomatch": "MATCH...
^
DETAIL: The input string ended unexpectedly.
CONTEXT: JSON data, line 1: {"geomatch": "MATCH","latitude":
SQL state: 22P02
Character: 4573
您可能正在寻找
SET data = data || ('{"geomatch": "MATCH","latitude":'||v.latitude||'}')::jsonb
-- ^^ jsonb ^^ text ^^ text
但这不是构建 JSON 对象的方式 - v.latitude
可能不是有效的 JSON 文字,甚至包含一些像 "", "otherKey": "oops"
这样的注入。 (不可否认,在您的示例中,您可以控制这些值,它们是数字,因此可能没问题,但这仍然是一种不好的做法)。相反,使用 jsonb_build_object
:
SET data = data || jsonb_build_object('geomatch', 'MATCH', 'latitude', v.latitude)
有两个问题。第一个是运算符优先级,防止将 jsonb
对象连接到读取的 text
对象。第二个是 text
部分的串联需要转换为 jsonb
.
这应该有效:
update contacts as c
set data = data || ('{"geomatch": "MATCH","latitude":'||v.latitude||'}')::jsonb
from (values (16247746,40.814140),
(16247747,20.900840),
(16247748,20.890570)) as v(contact_id,latitude)
where c.contact_id = v.contact_id
;