将键值对象发送到查询中的postgres

时间:2015-08-07 07:01:29

标签: sql postgresql

假设我有以下键值对象:

[{"Gin" : "Au"}, {"Beer": "US"}]

现在,我想执行以下查询:

UPDATE product SET location = "AU" WHERE name = "Gin";

UPDATE product SET location = "Beer" WHERE name = "US";

是否可以将一个键值对象发送到postgres,以便它自己进行映射?我想将一个请求中的所有内容包装到数据库中。

1 个答案:

答案 0 :(得分:1)

您基本上需要将您拥有的JSON数组转换为可以加入product表的一组行:

这样做有点复杂 - 至少我找不到更好的方法:

with elements (name, map) as (
  select json_object_keys(map::json) as name, map::json
  from json_array_elements_text('[{"Gin" : "Au"}, {"Beer": "US"}]') as map
)
select name, trim(both '"' from (map -> name)::text) as location
from elements;

我觉得应该有一个更优雅的解决方案将JSON转换为关系集,但我现在无法理解。

这将返回:

name | location
-----+---------
Gin  | Au      
Beer | US      

现在,此结果可用于更新产品表:

with elements (name, map) as (
  select json_object_keys(map::json) as name, map::json
  from json_array_elements_text('[{"Gin" : "Au"}, {"Beer": "US"}]') as map
)
update product 
  set location = r.location
from (
  select name, trim(both '"' from (map -> name)::text) as location
  from elements
) as r (name, location)
  where product.name = r.name;

由于你要做很多事情,我建议写一个函数将你的JSON变成一个合适的关系结果:

create function get_products(p_mapping text)
  returns table (name text, location text)
as 
$$
  with elements (name, map) as (
    select json_object_keys(map::json) as name, map::json
    from json_array_elements_text(p_mapping::json) as map
  )
  select name, trim(both '"' from (map -> name)::text) as location
  from elements;
$$
language sql;

然后更新看起来很简单:

update product 
  set location = r.location
from get_products('[{"Gin" : "Au"}, {"Beer": "US"}]') r
  where product.name = r.name;