• postgresql9.4新特性jsonb学习-update更新操作


    先科普下概念:PgSQL9.4 新增 JSONB 数据类型, JSONB 同时属于 JSON (JavaScript Object Notation) 数据类型,jsonb 和 json 的输入数据几乎完全通用,最大的差别体现在效率上,json 存储的数据几乎和输入数据一样,存储的是未解析的数据,调用函数时使用效率较低; 而 jsonb 存储的是分解的 binary 格式数据,使用时不需要再解析了,因此使用上效率较高; 另一方面 json 在写入时较快,而 jsonb 写入时由于需要转换导致写入较慢

    目前网上的资料大量的介绍jsonb 的查询操作,这里我不重复了

    官方文档介绍:http://www.postgresql.org/docs/9.4/static/datatype-json.html#JSON-CONTAINMENT

    francs博客:http://francs3.blog.163.com/blog/static/40576727201452293027868/

    json函数操作:http://www.postgresql.org/docs/9.5/static/functions-json.html

    我一直在想问题,select 都可以了,那么update 的时候是像传统的方式来操作吗?  如果是,那么对于json这样的数据更新就比较麻烦,

    能不能这样:

     update api set  jdoc->'guid'='ddddsxxx', jdoc->'name'='good' WHERE jdoc @> '{"company": "Magnafone"}'

    经过我测试发觉pgsql会报语法错误,那么这样肯定是不行了

    看来只能这样了:

    这样操作有一个弊端,那就是在更新的时候我就必须得知道content字段的全部内容,然后我才可以根据条件来更新,

    那么实战操作中 要知道content字段的全部内容 ,我又是不是要select出来,然后再 update,这样 就两个操作了。

    除了这样目前 对于 jsonb字段的更新确实没有更智能的方式,

    如果大家有更好的方式,欢迎留言

    后面我在国外论坛上找到了一些思路,

    http://stackoverflow.com/questions/18209625/how-do-i-modify-fields-inside-the-new-postgresql-json-datatype/23500670#23500670

    http://stackoverflow.com/questions/18209625/how-do-i-modify-fields-inside-the-new-postgresql-json-datatype

    Here are two helper functions, to achieve your goal (requires PostgreSQL 9.3+):

    This one can be used like UPDATEs (only updates an index, if it's already exists):

    CREATE OR REPLACE FUNCTION "json_array_update_index"(
      "json"            json,
      "index_to_update" INTEGER,
      "value_to_update" anyelement
    )
      RETURNS json
      LANGUAGE sql
      IMMUTABLE
      STRICT
    AS $function$
    SELECT concat('[', string_agg("element"::text, ','), ']')::json
      FROM (SELECT CASE row_number() OVER () - 1
                     WHEN "index_to_update" THEN to_json("value_to_update")
                     ELSE "element"
                   END "element"
              FROM json_array_elements("json") AS "element") AS "elements"
    $function$;

    This one can be used, like an UPSERT (updates an index, if it exists, or creates, if not -- using some default value to fill up unused indexes):

    CREATE OR REPLACE FUNCTION "json_array_set_index"(
      "json"            json,
      "index_to_set"    INTEGER,
      "value_to_set"    anyelement,
      "default_to_fill" json        DEFAULT 'null'
    )
      RETURNS json
      LANGUAGE sql
      IMMUTABLE
      STRICT
    AS $function$
    SELECT concat('[', string_agg((CASE "index"
                                     WHEN "index_to_set" THEN to_json("value_to_set")
                                     ELSE COALESCE("json" -> "index", "default_to_fill")
                                   END)::text, ','), ']')::json
      FROM generate_series(0, GREATEST("index_to_set", json_array_length("json") - 1)) AS "index"
    $function$;

    With these, you can UPDATE any json data, like: 【外国人的最终解决方式为:】

    UPDATE plan_base
    SET    atts = json_array_update_index(atts, 1, '{"planId":"71"}'::json)
    WHERE  id = 46;

    Important! Json arrays are indexed from 0 (unlike other PostgreSQL arrays). My functions respect this kind of indexing.

    SQLFiddle [意外收获]

    More about updating a JSON object:

    Update: functions are now compacted.

     我按照老外的这个思路把上面两段创建函数的语句加到数据库里面去

    然后再把之前的更新语句做了一下调整

    这些函数在我发本文的链连接里面有,这里不再重复

    建好后,采用select 调用函数来能够得到最终要更新的字符串如图所示

    最终更新还是得回到update上面

    这里最后我们看到更新成功,数字变过来了。

    这里通过写函数来处理,把查询构造都封装好了。方便处理,在一次conection里面就能处理,比其之前我们select update 在程序里处理有了一定的进步

    这里只是一种方式,如果诸位大神有更好的方式,欢迎留言

  • 相关阅读:
    ci 框架 报错级别 调整
    首页流氓广告的一种实现方法
    php中实现中文字符串的反转
    vmware 1021 错误解决 win7 64位
    isset 判断为POST信息是否为空 (笔记,持续更新)
    windows 下 ci 框架 命令行模式(cli)的使用
    ci 框架 excel 上传失败的处理
    php 日期处理(不断更新)
    svn的本地密码文件处理
    rpmdb open failed 的解决办法
  • 原文地址:https://www.cnblogs.com/fangyuan303687320/p/5062113.html
Copyright © 2020-2023  润新知