如何在PostgreSQL的更新语句中递增JSON键的值
如何在PostgreSQL的更新语句中递增JSON键的值
在更新关系表时:\n
CREATE TABLE foo ( id serial primary key, credit numeric); UPDATE foo SET bar = bar + $1 WHERE id = $2;
\n然而,在JSON中的等效操作无法实现:\n
CREATE TABLE foo ( id serial primary key, data json); UPDATE foo SET data->'bar' = data->'bar' + $1 WHERE id = $2;
\n我收到的错误是error: syntax error at or near \"->\"
- 这是相当模棱两可的。\n我该如何做呢?\n我使用的是postgres 9.3.4版本。\n
\n根据@GordonLinoff在下面的评论中提到的,我创建了一个功能请求:https://postgresql.uservoice.com/forums/21853-general/suggestions/6466818-create-update-delete-on-json-keys\n如果你也希望拥有这个功能,可以投票支持。
问题出现的原因是需要在PostgreSQL的更新语句中递增JSON键的值。解决方法是使用jsonb_set函数来实现递增操作。
首先,我们有一个包含嵌套JSONB数据的表,其中data_col列包含以下数据:
table_name.data_col = {"a": {"b": {"c": 1}}} // JSONB
我们想要将c的值递增为2,可以使用以下更新语句:
UPDATE table_name SET data_col = jsonb_set( data_col, '{a,b,c}', ( COALESCE( data_col#>'{a,b,c}', '0' ):: int + 1 ):: text :: jsonb ) WHERE id = '<id>';
在这个更新语句中,我们使用了jsonb_set函数来更新data_col列的值。jsonb_set函数接受三个参数:要更新的列,要更新的键路径,以及要设置的新值。
在这个例子中,我们使用路径'{a,b,c}'来指定要更新的键路径。我们使用COALESCE函数来获取现有值,如果该值不存在,则使用0作为默认值。然后,我们将该值转换为整数并递增1。最后,我们将递增后的值转换为文本并将其转换为jsonb格式。
最后,我们使用WHERE子句指定要更新的行的条件,其中id为待更新行的标识符。
需要注意的是:
- 使用类似'- 1'的方式可以进行递减等其他操作。
- PostgreSQL文档中的json操作非常有用。
问题出现的原因:
用户想要在Postgres的更新语句中递增JSON键的值。
解决方法:
可以使用jsonb来实现这一目标,至少在Postgres 9.5.2版本中是可以的。
首先创建一个包含jsonb类型列的表,设置默认值为空对象。
然后插入一些样本数据。
使用更新语句来原子地递增JSON键的值。
具体的步骤如下:
1. 使用||操作符将jsonb对象与字符串连接起来,从而将键设置为指定的值。
2. 使用COALESCE函数来检查键是否已经存在,如果不存在则将其默认值设置为0。
3. 使用::int将值转换为整数。
4. 使用CONCAT函数动态构建字符串。
5. 使用更新语句将新的jsonb对象赋值给计数器列。
通过这种方式,我们可以在更新语句中递增JSON键的值。
最后,通过SELECT语句来验证更新结果。
解决方法虽然不够优雅,但是却是有效的。
通过以上步骤,即可实现在Postgres的更新语句中递增JSON键的值。