如何根据json地图更新表?

时间:2017-08-19 09:11:04

标签: database postgresql

如果我有这张桌子

CREATE TABLE tmp (
    a integer,
    b integer,
    c text
);
INSERT INTO tmp (a, b, c) VALUES (1, 2, 'foo');

这个json:

{
    "a": 4,
    "c": "bar"
}

其中键映射到列名称,值是新值。

如何更新tmp表而不触及不在地图中的列?

我考虑构建一个可以在pl / pgsql中执行的SQL update语句的动态字符串,但似乎必须预先确定传递给USING的参数的数量。但是实际的参数数量是由地图中的键数决定的,这是动态的,所以这似乎是一个死胡同。

我知道我可以使用多个更新语句更新表,因为我循环键,但问题是我为表修改表(通过将更改的列插入另一个表)设置了触发器,因此必须在单个update语句中更新列。

我想知道是否可以使用json map动态更新表?

1 个答案:

答案 0 :(得分:0)

使用coalesce()。示例表:

with jsondata(jdata) as (
    values ('{"id": 1, "b": "new text"}'::jsonb)
)

update my_table set
    a = coalesce((jdata->>'a')::int, a),
    b = coalesce((jdata->>'b')::text, b),
    c = coalesce((jdata->>'c')::date, c)
from jsondata
where id = (jdata->>'id')::int;

select * from my_table;

 id | a |    b     |     c      
----+---+----------+------------
  1 | 1 | new text | 2017-01-01
(1 row) 

和查询:

    public class Songs {
    private String title;
    private Double duration;

    public Songs(String title, Double duration) {
        this.title = title;
        this.duration = duration;
    }

    public Songs(){}


    public String getTitle() {
        return title;
    }



    public Double getDuration() {
        return duration;
    }


    public static Songs addSong(String title, Double duration){
        return new Songs(title,duration);

    }
}



    import java.util.ArrayList;
import java.util.LinkedList;

public class Albums {
    private ArrayList<Songs> albums;
    private String name;
    private String title;

    public Albums(String name, String title) {
        this.albums = new ArrayList<>();
        this.name = name;
        this.title = title;
    }

    public boolean addSong(Songs songs){
        if(findSong(songs.getTitle())==null){
            this.albums.add(songs);
            return true;
        }else{
            System.out.println("Song alredy exist!");
            return false;
        }

    }

      private Songs findSong(String songName){
        for(int i=0;i<this.albums.size();i++){
            Songs currentSong = this.albums.get(i);
            if(currentSong.equals(songName)){
                return currentSong;
            }
        }
        return null;
    }
}