zoukankan      html  css  js  c++  java
  • Oracle中merge into的用法

    我们操作数据库的时候,有时候会遇到insertOrUpdate这种需求。

    如果数据库中存在数据就update,如果不存在就insert。

    以前的时候,需要额外select查询一下,如果有数据就update,如果没有数据就insert。

    而现在Orcale数据库都提供了 MERGE 方法来处理这种需求。

    MERGE 命令使用一条语句从一个或者多个数据源中完成对表的更新和插入数据。

    MERGE 语法:

    MERGE INTO [your table-name] [rename your table here] 
    USING ( [write your query here] )[rename your query-sql and using just like a table] 
    ON ([conditional expression here] AND [...]...) 
    WHEN MATCHED THEN [here you can execute some update sql or something else ] 
    WHEN NOT MATCHED THEN [execute something else here ! ] 

     这里我们创建两张学生信息表,以此为例来进行说明:

    -- Create table
    create table STUDENT_1
    (
      id               VARCHAR2(64) not null,
      code             VARCHAR2(30) not null,
      name             VARCHAR2(100) not null,
      age              NUMBER(3) not null,
      created_by       VARCHAR2(64) not null,
      creation_date    DATE not null,
      last_updated_by  VARCHAR2(64) not null,
      last_update_date DATE not null,
      last_update_ip   VARCHAR2(64) not null,
      version          NUMBER(16) not null
    )
    tablespace MES614
      pctfree 10
      initrans 1
      maxtrans 255
      storage
      (
        initial 16
        next 8
        minextents 1
        maxextents unlimited
      );
    -- Add comments to the table 
    comment on table STUDENT_1
      is '1班学生信息表';
    -- Add comments to the columns 
    comment on column STUDENT_1.id
      is 'ID';
    comment on column STUDENT_1.code
      is '学生证号';
    comment on column STUDENT_1.name
      is '学生姓名';
    comment on column STUDENT_1.age
      is '年龄';
    comment on column STUDENT_1.created_by
      is '创建人';
    comment on column STUDENT_1.creation_date
      is '创建日期';
    comment on column STUDENT_1.last_updated_by
      is '最后更新人';
    comment on column STUDENT_1.last_update_date
      is '最后更新时间';
    comment on column STUDENT_1.last_update_ip
      is '最后更新IP';
    comment on column STUDENT_1.version
      is '版本';
    -- Create/Recreate primary, unique and foreign key constraints 
    alter table STUDENT_1
      add constraint PK_STUDENT_1 primary key (ID)
      using index 
      tablespace MES614
      pctfree 10
      initrans 2
      maxtrans 255
      storage
      (
        initial 64K
        next 1M
        minextents 1
        maxextents unlimited
      );

    学生信息表2除了和学生信息表1名称不一样之外,结构完全一致,所以这里就不在把学生信息表2(student_2)的建表语句放上来了。(Mes614是表空间名)

    我们先手动的在student_2表中插入一些数据,然后先单独的写两个sql,分别将student_2中的数据插入或者更新到student_1中:

    --将student_2中的数据插入到student_1中
    insert into student_1
      (id,
       code,
       name,
       age,
       created_by,
       creation_date,
       last_updated_by,
       last_update_date,
       last_update_ip,
       version)
      select t.id,
             t.code,
             t.name,
             t.age,
             t.created_by,
             t.creation_date,
             t.last_updated_by,
             t.last_update_date,
             t.last_update_ip,
             t.version
        from student_2 t
        --where ...
    
    --将student_1中数据除ID外随便乱改,然后通过merge into sql将其更新回来
    merge into student_1 t
    using (select t1.id,
                  t1.code,
                  t1.name,
                  t1.age
             from student_2 t1) me --这里可以只查出需要的字段
    on (t.id = me.id)  
    when matched then  --当on()中条件成立时执行
      update
         set t.code = me.code,
             t.name = me.name,
             t.age  = me.age,
             t.version = t.version + 1;

    下面我们就用merge into sql来同时进行插入和更新操作:

    merge into student_1 t
    using (select t1.id,
                  t1.code,
                  t1.name,
                  t1.age,
                  t1.created_by,
                  t1.creation_date,
                  t1.last_updated_by,
                  t1.last_update_date,
                  t1.last_update_ip,
                  t1.version
             from student_2 t1) me --这里可以只查出需要的字段
    on (t.id = me.id)  
    when matched then  --当on()中条件成立时执行
      update
         set t.code = me.code,
             t.name = me.name,
             t.age  = me.age,
             t.version = t.version + 1
    when not matched then  --当on()中条件不成立时执行这部分
      insert
        (id,
         code,
         name,
         age,
         created_by,
         creation_date,
         last_updated_by,
         last_update_date,
         last_update_ip,
         version)
      values
        (me.id, 
         me.code, 
         me.name, 
         '22',
         me.created_by,
         me.creation_date,
         me.last_updated_by,
         me.last_update_date,
         me.last_update_ip,
         me.version);

    注意事项:

    Merge Into的原理是,从using 搜出来的结果逐条与on条件匹配,然后决定是update还是Insert。 当USING后面的sql没有查询到数据的时候,Merge Into语句是不会执行update和Insert操作的。

    所以要想让Merge Into正常运行,要保证USING 后面的SELECT有数据。

  • 相关阅读:
    vue之实现日历----显示农历,滚动日历监听年月改变
    vue填坑之全局引入less,scss,styl文件
    vue填坑之引入iconfont字体图标
    纯JS实现带小圆点缩略图及左右箭头的轮播图
    canvas绘制时钟
    CSS实现鼠标移入图片边框有小三角
    jquery之.outerWidth()
    CSS ::selection 选中文字效果
    LINUX下用Nginx和Node.js构建一个简单的项目(4)
    LINUX下用Nginx和Node.js构建一个简单的项目(3)
  • 原文地址:https://www.cnblogs.com/1012hq/p/11364698.html
Copyright © 2011-2022 走看看