Oracle实现记录存在则修改,不存在则插入


  • 在Oracle中创表

declare num number;   
begin
    select count(1) into num from user_tables where table_name='ACCOUNT';   
    if num > 0 then   
      dbms_output.put_line('存在!');   
      execute immediate 'drop table ACCOUNT ';
      end if;   
      execute immediate 'create table Account
                        (
                                AccountID nvarchar2(50) primary key,
                                AccountName nvarchar2(50) 
                        )';  
      dbms_output.put_line('成功创建表!');end;

Oracle中没有函数来判断一个表是否存在,那就只能通过委婉的方式来实现,Oracle中就有了select  * from user_tables,通过查询系统表,判断这个表在数据库中是否存在,如果存在就删除,然后再创建。

  • 隐式游标法SQL%NOTFOUND   SQL%FOUND

SQL%NOTFOUND 是SQL中的一个隐式游标,在增删查改的时候自动打开,如果有至少有一条记录受影响,都会返回false,这就就巧妙的构思出了第一种解决方案:

begin
update account set AccountName = '修改-a' where AccountID = '5';
IF SQL%NOTFOUND THEN
   insert into account(AccountID,AccountName) values('5','添加-b');
   END IF;
end;

先根据唯一ID到数据表中修改一条记录,如果这条记录在表中存在,则修改,并且SQL%NOTFOUND返回false。如果修改的记录不存在,SQL%NOTFOUND返回true,并且执行插入语句。


  • 异常法 DUP_VAL_ON_INDEX

当Oracle语句执行时,发生了异常exception进行处理

begininsert into account(AccountID,AccountName) values('6','添加-b');
exception 
when DUP_VAL_ON_INDEX then begin update account set AccountName = '修改-b' where AccountID = '6';
end;
end;

当往表中插入一条数据,因为表中有主键约束,如果插入的数据在表中已经存在,则会抛出异常,在异常抛出后进行修改。


  • 虚拟表法  dual

dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录。

declare t_count number;
beginselect count(*) into t_count from dual where exists(select 1 from account where AccountID='11');
if t_count< 1 then
  dbms_output.put_line('添加');  
  insert into account(AccountID,AccountName) values('11','添加-11');
else
  dbms_output.put_line('修改');  
  update account set AccountName = '修改-11' where AccountID = '11';  
  end if;
end;

先声明一个变量t_count,表dual表的值赋给t_count,如果这个值小于1,表示记录不存在,进行插入操作,反之,存在就进行修改操作。

  • no_data_found法

先查找要插入的记录是否存在,存在则修改,不存在则插入。具体的实现如下:

declare t_cols number;beginselect AccountName into t_cols from account where AccountID = '8';
exception 
when no_data_found then begin 
   --dbms_output.put_line('添加');
   insert into account(AccountID,AccountName) values('8','添加-8');end;when others then 
  begin
    --dbms_output.put_line('修改');
    update account set AccountName = '修改-8' where AccountID = '8';
    end;
    end;

  • merge法

MERGE INTO table_name alias1   
USING (table|view|sub_query) alias2  
ON (join condition)   
WHEN MATCHED THEN   
    UPDATE table_name SET col1 = col_val1WHEN NOT MATCHED THEN   
    INSERT (column_list) VALUES (column_values);


上一篇

评论



分享

我的公众号

恩波的公众号

最新加入

最新评论

lwj: 你好,我刚看了你发的这个帖子,不知道现在评论是否能看到。我现在在做这个功能,可以用。但我这还有个需求就是,可以推送多张,我在cardList里,把需要推送的卡券,都添加上了,微信端页面也显示正确,有个领取按钮,但可以领取多次,每次卡包里多一张,而且这张是列表上的第一张 。。请问,你有没有遇到过 推送多张的情况 查看原文 05月15日 14:29
roly: 另外添加卡券接口的参数cardId: "xxxxxxxxxxxxxxxxxxxxxx", cardExt: '{"timestamp":"1426222398","signature":"fdd892770eb681e925f92acb9015c75107b2227a"}' 是通过自己服务获取以上参数 还是用js在html5页面直接生产签名参数? 查看原文 05月12日 16:41
roly: 您好,请问怎么查询当前用户卡券是否领取状态? 查看原文 05月12日 16:20
所谓爱人: 可不可以加个好友QQ1217994113 查看原文 04月01日 18:47
17688905252: 看了好多说是要加上这个样式的,但是加上之后为什么还是一点反应都没有呢... 查看原文 04月01日 14:55

赞助商