如果您可以升级到Postgresql 9.5,则可以使用jsonb_set
命令,正如其他人所提到的那样。
在以下每个SQL语句中,我已省略了where
子句以缩短长度; 显然,您需要将其添加回去。
更新名称:
UPDATE test SET data = jsonb_set(data, '{name}', '"my-other-name"');
替换标签(而不是添加或删除标签):
UPDATE test SET data = jsonb_set(data, '{tags}', '["tag3", "tag4"]');
替换第二个标签(从0开始计数):
UPDATE test SET data = jsonb_set(data, '{tags,1}', '"tag5"');
添加标签(只要标签数量少于999个,这将起作用;将参数999更改为1000或更多会生成错误。在Postgres 9.5.3中似乎不再是这种情况;可以使用更大的索引):
UPDATE test SET data = jsonb_set(data, '{tags,999999999}', '"tag6"', true);
移除最后一个标签:
UPDATE test SET data = data #- '{tags,-1}'
< p > 复杂更新(删除最后一个标签,插入一个新标签并更改名称):
UPDATE test SET data = jsonb_set(
jsonb_set(data #- '{tags,-1}', '{tags,999999999}', '"tag3"', true),
'{name}', '"my-other-name"');
需要注意的是,在这些例子中,您实际上并没有更新 JSON 数据的单个字段。相反,您正在创建一个临时的、修改过的版本,并将该修改后的版本重新分配给列。实际上,结果应该是相同的,但牢记这一点可以使复杂的更新(例如最后一个示例)更加易于理解。
在复杂的示例中,有三个转换和三个临时版本:首先,删除了最后一个标签。然后,通过添加新标签来转换该版本。接下来,通过更改name
字段来转换第二个版本。最终版本替换了data
列中的值。
jsonb_set
调用的输入是内部调用的输出,并且该内部调用的输入是data #- '{tags,-1}'
的结果。即原始数据中删除了最后一个标签。 - Jimothy{tags,0}
,那就意味着“数组tags
的第一个元素”,这样我就可以给该元素赋新值。通过使用大数而不是0,它不会替换数组中的现有元素,而是向数组添加一个新元素。但是,如果数组实际上有超过999,999,999个元素,则这将替换最后一个元素而不是添加一个新元素。 - Jimothy