织梦CMS - 轻松建站从此开始!

罗索

PL/SQL: 更好的检查记录是否存在的方法

jackyhwei 发布于 2011-06-24 09:10 点击:次 
看见这个标题的人可能会嘲笑我,检查记录是否存在不是很简单吗:SELECT count(1) FROM tab WHERE id=key;当然,这样肯定是可以的。但是,如何结合业务,写出更高效更简洁的代码呢?
TAG:

看见这个标题的人可能会嘲笑我,检查记录是否存在不是很简单吗:SELECT count(1) FROM tab WHERE id=key;当然,这样肯定是可以的。但是,如何结合业务,写出更高效更简洁的代码呢?

情况一:将存在于A表但不存在于B表的数据插入到B表,将存在于A表也存在于B表的数据更新到B表,可以这样写:
    UPDATE B SET b.field=(select field FROM a WHERE a.id=b.id)
     WHERE EXISTS(SELECT 1 FROM a WHERE a.id=b.id);
    INSERT INTO B
    SELECT a.id, a.field
    FROM a
    WHERE NOT EXISTS(SELECT 1 FROM b WHERE b.id=a.id);
    COMMIT;
    --这个例子通过exists来判断记录是否存在,主要用于两个集合(表)的操作
情况二:插入一条记录到A,如果A中已经有这条记录,则更新记录。
    --(我们反过来写,先更新,再插入)
    UPDATE A SET field=value WHERE id=key;
    IF SQL%NOTFOUND THEN   --当一条记录都没更新的时候,SQL%NOTFOUND这个游标变量会为TRUE
        INSERT INTO a VALUES(key, value);
    END IF;
    COMMIT;
    --通过使用SQL%NOTFOUND这个游标变量,比起先SELECT COUNT(1)对应的记录,肯定更快
情况三:插入一条记录到A,如果记录已经存在,就放弃
    --前提条件是:表存在唯一索引(或主键)
    BEGIN
       INSERT INTO a VALUES(key, value);
       COMMIT;
    EXCEPTION
       WHEN DUP_VAL_ON_INDEX THEN    --当发生主键冲突的时候,会产生DUP_VAL_ON_INDEX 的异常
           ROLLBACK;
           RETURN;
    END;
    --这里使用异常来代替去查询记录是否存在,既然发生了唯一索引冲突,则记录一定是存在的。

情况四:如果A表记录不存在,则我们做一些与A表无关的操作
    DECLARE
         v_temp number(10);
    BEGIN
         SELECT 1 INTO v_temp FROM A WHERE id=key AND rownum<=1;
    EXCEPTION
         WHEN NO_DATA_FOUND THEN
               --do something
    END;

    --使用select into语句如果没有找到记录,会引发NO_DATA_FOUND的异常。

 

    --注意:如果ID不是唯一的,要加上rownum<=1

 

    --这种方法比起select count(1)来,只用检查到第一条存在的记录即可,速度很快。

(ah__fu)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201106/14608.html]
本文出处:hi.baidu.com/ah__fu 作者:ah__fu
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容