• “德国战车”成了“老爷车”? 卫冕前景令人担忧 2019-09-16
  • 比iPad更白菜价:给自己个喜新厌旧换平板的理由 2019-09-09
  • 网友建言——黄河新闻网 2019-09-07
  • 打造时尚达人般的理想生活-热门标签-华商网数码 2019-09-06
  • “爸爸是交警”刷屏朋友圈  我用各种姿势陪你 2019-09-02
  • 马克思主义通过指导无产阶级革命建立起部分社会财富公有制而改变了人类历史发展进程,离开部分社会财富公有制的建立来谈“改变人类历史发展进程”纯粹是无稽之谈。 2019-09-02
  • 谌龙,男羽的大旗你不扛也得扛 2019-08-31
  • [酷]此文已经把马克思理论、边际理论、人类需求层次理论、生物学理论、心理学理论、社会管理学理论等理论在哲学层面完美融合了! 2019-08-31
  • 凤凰网旅游发布大风号政府旅游影响力榜单(2018年5月) 2019-08-30
  • 中国动力电池市场竞争加剧 70家公司仅占3成份额 2019-08-30
  • 端午节假期间全国道路交通平稳有序 2019-08-29
  • 你把我抱紧 我帮你扶伞 2019-08-17
  • 榕城监狱及时调解服刑人员家属建房纠纷 2019-08-15
  • 市委把全国两会精神原汁原味传达到基层 2019-08-15
  • 大同能源革命跑出发展“加速度” 2019-08-14
  • 当前位置:山西十一选五遗漏10-建站教程-数据库教程-PostgreSQL-PostgreSQL实现批量插入、更新与合并操作的方法

    山西十一选五任六最大遗漏数据:PostgreSQL实现批量插入、更新与合并操作的方法

    时间:2019-02-18来源/作者:隔叶黄莺 编辑:源码库 文章热度:

    山西十一选五遗漏10 www.fqjb.net 前言

    就在 2019 年 1 月份微软收购了 PostgreSQL 数据库的初创公司 CitusData, 在云数据库方面可以增强与 AWS 的竟争。AWS 的 RDS 两大开源数据库就是 MySQL(Aurora 和 MariaDB 是它的变种) 和 PostgreSQL。

    而 PostgreSQL 跳出了普通关系型数据库的类型约束,它灵活的支持 JSON, JSONB, XML, 数组等类型。比如说字段类型可以是各种形式的数组,一维或多维。

    create table t1(
     address varchar(5)[3],
     counter integer[3][3],
     schedule text[][]
    )

    上面只是认识了一下 PostgreSQL 这一亮眼的特性,本篇重点不在如何定义操作数组类型的字段,而是对于普通的非数组字段类型如何用与数组相关的 unnest 关键字进行记录的批量插入,更新以及合并操作。

    在正式使用介入 unnest 之前先熟悉一下 PostgreSQL 的 upsert(update insert) 操作。受其他数据库的影响,总以后 PostgreSQL 也应该支持 merge into 语句,而且竟然 PostgreSQL 官方也有文档介绍 MERGE 有模有样的,然而试了一下根本就不支持 merge into 操作。

    普通的 insert upsert 操作

    不过 PostgreSQL 有另一种 upsert 的语法,或称之为 insert on conflict,也就是 PostgreSQL 加强版的 insert 语句。如下

    INSERT INTO users (id, level)
    VALUES (1, 0)
    ON CONFLICT (id) DO UPDATE
    SET level = users.level + 1;

    即插入记录时存在相同的主键可对原记录的某些列进行更新,否则插入该记录。更详细的 insert 语法请参考官方文档 PostgreSQL INSERT。

    注意到上面的 upsert 只是应用于处理单条记录,而本文将要讨论到的是批量的处理。我们知道 insert 时可以同时插入多行记录,那么这个  upsert 语法是否也能同时操作多行记录呢?我们大胆假设,小心求证,那就动手一试吧

    create table users(
     id int primary key,
     level int
    )

    创建一个表 users, 然后插入一条记录

    INSERT INTO users (id, level) VALUES (1, 0)

    查询 select * from users 表的内容如下

    PostgreSQL,批量,插入,更新,合并

    执行批量的 insert

    INSERT INTO users (id, level)
    VALUES (1, 3), (2, 1)
    ON CONFLICT (id) DO UPDATE
    SET level = excluded.level;

    理看看 users 表中的内容

    PostgreSQL,批量,插入,更新,合并

    我们看到已存在行(id=1) 的 level 更新为新的值 3, 并且插入新行。

    这里注意到我们用到一个关键字 excluded 用于引用 INSERT 语句中 VALUES 提供的值,相应的表名 users 用于引用表中原有的值。

    基于 unnest 的 upsert 操作

    前面仍然是写作此文的意外收获,实际上想要总结的是 unnest 关键字在批量操作中的作用。下面来进行演示

    create table testunnest(
      id int primary key,
     col1 int,
     col2 varchar(50)
    )

    创建一个表并用 unnest 提供并行数组来进行批量插入

    insert into testunnest(id, col1, col2) 
     values (unnest(array[1,2]), unnest(array[30,40]), unnest(array['val1', 'val2']));

    这时候表中的内容为

    PostgreSQL,批量,插入,更新,合并

    从执行效果来看,它与下面的 insert 语句是等效的

    insert into testunnest(id, col1, col2) values
     (1, 30, 'val1')
     (2, 40, 'val2')

    换成成 unnest(array[..]) 的形式有一种行转列的行为。

    用 unnest 加上 unsert 再执行一次插入

    insert into testunnest(id, col1, col2)
     values (unnest(array[2,3]), unnest(array[80,90]), unnest(array['valupdated', 'val3']))
     on conflict (id) do update
     set col1 = excluded.col1, col2 = excluded.col2

    再查看表的内容如下

    PostgreSQL,批量,插入,更新,合并

    unnest 与 JDBC 操作

    insert into users values (?, ?) on conflict.... 的 SQL 语句的单条记录或批量操作(addBatch(), executeBatch()) 就不多说了,主要看下用 JDBC 怎么对 unnest 进行赋值操作。

    PreparedStatement pstmt = conn.prepareStatement(
     "INSERT INTO testunnest(id, col1, col2) " +
      " VALUES (unnest(?), unnest(?), unnest(?))" +
      " ON CONFLICT (id) DO UPDATE" +
      " SET col1 = excluded.col1, col2 = excluded.col2"
    );
     
    pstmt.setArray(1, conn.createArrayOf("int", new Integer[]{2, 3}));
    pstmt.setArray(2, conn.createArrayOf(JDBCType.INTEGER.getName(), new Integer[]{80, 90}));
    pstmt.setArray(3, conn.createArrayOf("varchar", new String[]{"val1", "val2"}));
     
    int update = pstmt.executeUpdate();
    System.out.println(update); //影响的记录数是 2

    点位符要用 unnest(?),设置参数时要用 setArray(), 参数用 conn.createArrayOf(type, array) 来指定。需要指明数组中的元素类型,这么普通的 setInt(), setString() 是一个意思。

    用不着转换为 PostgreSQL 特定的 PreparedStatement 来操作,用 JDBC 通用的 PreparedStatement 接口就能支持对数组类型的赋值,难道是其他类型的数据库也能支持类似的数组操作?

    链接:

    Upsert Records with PostgresSQL 9.5

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对ASPKU源码库的支持。


    注:相关教程知识阅读请移步到PostgreSQL频道。
    下一篇:没有了
    相关PostgreSQL
    热门标签

  • “德国战车”成了“老爷车”? 卫冕前景令人担忧 2019-09-16
  • 比iPad更白菜价:给自己个喜新厌旧换平板的理由 2019-09-09
  • 网友建言——黄河新闻网 2019-09-07
  • 打造时尚达人般的理想生活-热门标签-华商网数码 2019-09-06
  • “爸爸是交警”刷屏朋友圈  我用各种姿势陪你 2019-09-02
  • 马克思主义通过指导无产阶级革命建立起部分社会财富公有制而改变了人类历史发展进程,离开部分社会财富公有制的建立来谈“改变人类历史发展进程”纯粹是无稽之谈。 2019-09-02
  • 谌龙,男羽的大旗你不扛也得扛 2019-08-31
  • [酷]此文已经把马克思理论、边际理论、人类需求层次理论、生物学理论、心理学理论、社会管理学理论等理论在哲学层面完美融合了! 2019-08-31
  • 凤凰网旅游发布大风号政府旅游影响力榜单(2018年5月) 2019-08-30
  • 中国动力电池市场竞争加剧 70家公司仅占3成份额 2019-08-30
  • 端午节假期间全国道路交通平稳有序 2019-08-29
  • 你把我抱紧 我帮你扶伞 2019-08-17
  • 榕城监狱及时调解服刑人员家属建房纠纷 2019-08-15
  • 市委把全国两会精神原汁原味传达到基层 2019-08-15
  • 大同能源革命跑出发展“加速度” 2019-08-14
  • 2元彩票网走势图大全 秒速飞艇万喜 ag手机客户端怎么登录 奥迅球探 2019女子足球世界杯时间 体育彩票七位数15173期开奖号码 快三和值投注技巧 qq游戏中没有十三水 体彩20选5中三个有奖吗 辽宁快乐12秘籍 网站广东彩票 双色球基本走势图图表 广西快三专家预测推荐 湖北十一选五推荐号码 cba什么时候开赛