本文转自:http://blog.csdn.net/hollboy/article/details/7550171

对于Oracle中没有 if exists(...) 的语法,目前有许多种解决方法,这里先分析常用的三种,推荐使用最后一种

第一种是最常用的,判断count(*)的值是否为零,如下

declare
v_cnt number;
begin
select count(*) into v_cnt from T_VIP where col=1;
if v_cnt = 0 then
dbms_output.put_line('无记录');
end if;
end;

首先这种写法让人感觉很奇怪,明明只需要知道表里有没有记录,却去统计了全表的记录数。 这种方式对于小表而言可以接受,一旦表记录很多的时候,性能问题就非常严重 因此有人就作了些修改,改成 select count(*) into v_cnt from T_VIP where col=1 and rownum=1 看起来似乎解决了性能问题,但是分析执行计划可以知道,实际上是一样的,不推荐使用。

第二种是所谓进攻式编程,不作预先判断,而是直接默认通过判断,然后使用 exception 来捕获异常 比如我这里不判断表中是否有满足条件的记录,默认它有,如果没有就在异常中进行处理

declare
v_1 number;
begin
select vip_level into v_1 from T_VIP where 1=0;
exception
when no_data_found then
dbms_output.put_line('无记录');
end;

这种方式从性能上讲比第一种要好得多 不过首先它没办法适应所有的情况,如第一段代码它就没办法改造 其次这种代码看起来让人觉得好像是发生了异常,而不是正常运行,从而造成混乱,不推荐使用。

第三种是利用 Oracle 原有的 Exists 语法,如下

declare   v_cnt number; begin   select count(*)     into v_cnt     from dual    where exists (select * from t_vip where col=1);   if v_cnt = 0 then     dbms_output.put_line('无记录');   end if; end;

declare
v_cnt number;
begin
select count(*)
into v_cnt
from dual
where exists (select * from t_vip where col=1);
if v_cnt = 0 then
dbms_output.put_line('无记录');
end if;
end;

通过在语句的外面套上一层dual,来使用oracle原有的exists语法 虽然和第一种看起来类似,但分析执行计划可以知道,性能比以上两种都要好得多,与MSSQL的 if exists 最接近,推荐使用。

可以把判断封装成一个函数以方便使用,代码如下

CREATE OR REPLACE FUNCTION EXISTS2 (IN_SQL IN VARCHAR2)
RETURN NUMBER
IS
/**********************************************************
* 使用示例
* begin
* if EXISTS2('select * from dual where 1=1')=1 then
* dbms_output.put_line('有记录');
* else
* dbms_output.put_line('无记录');
* end if;
* end;
*****************************************************************/
V_SQL VARCHAR2(4000);
V_CNT NUMBER(1);
BEGIN
V_SQL := 'SELECT COUNT(*) FROM DUAL WHERE EXISTS (' || IN_SQL || ')';
EXECUTE IMMEDIATE V_SQL INTO V_CNT;
RETURN(V_CNT);
END;

对于常用的insert判断还有更简单的写法,比如以下代码

if not exists(select * from table1 where id=1)    insert into table1 values(1,'a');

可以改写成 insert   when (not exists(select * from table1 where id=1)) then into table1 select 1 as id, 'a' as data from dual;

-

再比如以下的代码 if not exists(select * from table1 where id=2)    insert into table1 values(2,'b') else    update table1 set data='b' where id=2;

可以改写成

merge into table1 his
using
(
select 2 as id, 'b' as data from dual
) src
on (his.id=src.id)
when matched then
update set his.data=src.data where id=src.id
when not matched then
insert values(src.id,src.data);

这里附带说下,有人喜欢把count(*)写成count(列名),不推荐后一种,因为列名是需要额外的操作,去查询系统表来定位列信息

另外count(1)和count(*)没有差别,推荐使用count(*)直观明了

最新文章

  1. JavaScript的two-sum问题解法
  2. C#记录程序运行时间记录显示
  3. Web APi之EntityFramework【CRUD】(三)
  4. android之简单图形绘制
  5. LoadRunner脚本设计、场景设计和结果分析
  6. 使用django的ImageField和from制作上传图片页面
  7. wdatepicker minDate&maxDate
  8. jQuery源码笔记——四
  9. phpMyAdmin 手动输入数据库服务器IP
  10. 版本控制器——Egit使用方法
  11. Linux防火墙配置—SNAT1
  12. 官方JwPlayer去水印步骤
  13. MySQL学习3 - 数据表的操作
  14. python(一)——初识与变量
  15. JavaScript 六大类运算符(详细~)
  16. Elasticsearch5.5.1插件开发指南
  17. 光流法(optical flow)
  18. 在IIS上SSL的部署和启动SSL安全【转】
  19. Node使用淘宝 NPM 镜像
  20. signal(SIGCHLD, SIG_IGN)和signal(SIGPIPE, SIG_IGN);

热门文章

  1. JFrog Artifactory
  2. SystemID
  3. poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和(模板)
  4. SFML从入门到放弃(2) 图像和音频
  5. vm虚拟机安装,配置与使用
  6. [ActionScript 3.0] 自定义右键菜单
  7. iOS开发之静态库.a 以及合并
  8. c语言-猜生日算法
  9. 面试笔试(C++部分)
  10. Git的一些用法