zoukankan      html  css  js  c++  java
  • oracle--insert

    常规insert语法就不说了,还有些特殊用法

    1.  insert all 

     into table1(col1,col2) values(v1,v2)

     into table2(col1,col2) values(v1,v2)

       ......

       select ...;

    后面的select直接影响前面的into,查询出的每条记录分别执行一次into

    示例:

    insert all into t_banks values(id,name,al_name) select * from t_banks; --t_banks表中的数据会加倍,values是后面select出的列名

    insert all into t_banks values('1','1','1') select 1 from dual; --t_banks表插入一条记录('1','1','1')

    2. insert all/first
        when ? then
            into table1(col1,col2) values(v1,v2)
        when ? then
            into table2(col1,col2) values(v1,v2)
        else
            into table3(col1,col2) values(v1,v2)
        select ...;

    all有条件的插入,会依次判断每个符合的条件然后into

    first有条件的插入,会找到第一个满足的条件然后into,后面的就不判断了

    ps:业务中有这样的场景,如果有满足条件的记录就不插入,否则插入。

    单线程下先select再insert是ok的,但是如果用户通过界面同时操作就有可能在数据库插入同一数据。

    解决方法如下

    • 在service层对方法synchronized,粗暴有效

       如果项目需要集群就不好控制了

    • 数据库层面,在表上加唯一约束,需要动表

       场景:现有一张表存借款需求,每条需求有一个编号,如果有在处理中的需求,相同编号的借款需求不允许再次插入,否则可以再次把借款需求插入表,进行处理

       解决:表上加一个字段SEQ,存同一编号的多条记录的序号1,2,3,4......,编号和SEQ添加唯一键

          这个时候如果表中已有数据,使用下面的sql为已有数据添加SEQ

          merge into t_loan_request lr

          using(

            select decode(rownum-min_sno,0,1,rownum+1-min_sno)sno,a.lr_id

            from

            (select lr_applyid,lr_id from t_loan_request order by lr_applyid,lr_id)a,

            (select lr_applyid,min(rownum) min_sno

            from(select lr_applyid,lr_id from t_loan_request order by lr_applyid,lr_id)r

            group by lr_aplyid)b

            where a.lr_applyid=b.lr_applyid

          )req

          on (lr.lr_id=req.lr_id)

          when matched then

            update set lr.seq=req.sno  

          

          插入数据sql如下:

          insert into t_loan_request(lr_id,lr_applyid,lr_requeststatus,seq)

          select seq_loan_request.nextval,'000123','0',(select count(1)+1 from t_loan_request where lr_applyid='000123')

          from dual 

          where not exists(select lr_id from t_loan_request where lr_requeststatus!='3' and lr_applyid='000123')

          上面的语句如果并发,lr_applyid+seq相同,数据库检查唯一性,最终导致只有一条记录入库成功

          

          或者使用merge插入语句

          merge into t_loan_request lr

          using (select count(1) cnt from t_loan_request where lr_requeststatus!='3' and lr_appplyid='000123')req

          on(req.cnt<1)

          when matched then

          insert (lr_id,lr_applyid,lr_requeststatus,seq)

          values(seq_loan_request.nextval,'000123','0',(select count(1)+1 from t_loan_request where lr_applyid='000123'))

          和上面的sql效果一样

    • sql改造,网上看的,但觉得不可靠

       INSERT INTO T_TABLE SELECT ?,?,?,?,? FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM T_TABLE T WHERE T.FIELD1 = ? AND T.FIELD2 = ?)

       只是依靠这一条语句,如果并发,都符合where条件,同时入库插入成功

  • 相关阅读:
    网游内存数据库的设计(1)
    基于用户级线程的远程调用效率测试
    实现c协程
    KendyNet for linux
    开源一个lua的网络库
    C语言重写网络发送/接收封包
    C协程使用举例
    各种内存分配器的对比测试
    KendyNet性能测试
    C协程实现的效率对比
  • 原文地址:https://www.cnblogs.com/yhzh/p/5386637.html
Copyright © 2011-2022 走看看