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;
通过在语句的外面套上一层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. 如何解决Maven和SBT下载Jar包太慢
  2. ORA-12560: TNS: 协议适配器错误
  3. IntelliJ IDEA 教程设置讲解
  4. laravel in centos
  5. 使用Navicat连接数据库,不能创建外键
  6. iPhone中修改iMessage关联手机号码的终极方法
  7. Maximum Product Subarray动态规划思想
  8. 【技术贴】解决Program Files文件夹消失
  9. swift 中String常用操作
  10. CVTE 一面
  11. 开源Office Word——DocX
  12. Extjs表单控件入门
  13. windows ORA-12560: TNS: 协议适配器错误
  14. Nginx中的信号量(信号控制)
  15. 基于注解的SpringMVC添加其他的Servlet、Filter以及Listener
  16. 熟悉使用Github,VS进行项目的开发(第二次作业)
  17. java命令--jstat 工具使用
  18. SpringCloud-分布式配置中心(基于SpringBoot2.X)
  19. 删除mysql数据库中表分区数据
  20. Sequel Pro for Mac(MySQL 数据库管理工具)破解版安装

热门文章

  1. IX Samara Regional Intercollegiate Programming Contest F 三分
  2. 七牛云的cdn配置
  3. js数据类型判断
  4. 洛谷 [P1552] 派遣
  5. jQuery1.4与json格式兼容问题
  6. using要写多少
  7. Eclipse下搭建Maven框架
  8. 查询/删除/建立DB2数据表的主键
  9. 无法启动Visual Studio的localhost web服务器,端口"xxxx"已被使用
  10. [Python Cookbook] Numpy Array Slicing and Indexing