Oracle中没有 if exists(...)的解决方法
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(*)直观明了
Oracle中没有 if exists(...)的解决方法的更多相关文章
- Oracle中没有 if exists(...)
对于Oracle中没有 if exists(...) 的语法,目前有许多种解决方法,这里先分析常用的三种,推荐使用最后一种 第一种是最常用的,判断count(*)的值是否为零,如下declare v ...
- [转]Oracle中没有 if exists(...)
本文转自:http://blog.csdn.net/hollboy/article/details/7550171 对于Oracle中没有 if exists(...) 的语法,目前有许多种解决方法, ...
- linux下安装Oracle时交换空间不足的解决方法
摘:linux下安装Oracle时交换空间不足的解决方法 linux上安装Oracle时交换空间不足的解决办法 增加交换空间有两种方法: 严格的说,在系统安装完后只有一种方法可以增加swap,那就是本 ...
- VS2012中丢失ArcGIS模板的解决方法
VS2012中丢失ArcGIS模板的解决方法 由于ArcGIS10.0(for .NET)默认是用VS2010作为开发工具的,所以在先安装VS2012后装ArcGIS10.0 桌面版及ArcObjec ...
- js中style.display=""无效的解决方法
本文实例讲述了js中style.display=""无效的解决方法.分享给大家供大家参考.具体解决方法如下: 一.问题描述: 在js中我们有时想动态的控制一个div显示或隐藏或更多 ...
- java开发中遇到的问题及解决方法(持续更新)
摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...
- ORACLE 中IN和EXISTS比较
ORACLE 中IN和EXISTS比较 EXISTS的执行流程 select * from t1 where exists ( select null from t2 where y = x ...
- navicat连接oracle数据库报ORA-28547: connection to server failed, probable Oracle Net admin error错误的解决方法
原文:navicat连接oracle数据库报ORA-28547: connection to server failed, probable Oracle Net admin error错误的解决方法 ...
- SpringBoot拦截器中无法注入bean的解决方法
SpringBoot拦截器中无法注入bean的解决方法 在使用springboot的拦截器时,有时候希望在拦截器中注入bean方便使用 但是如果直接注入会发现无法注入而报空指针异常 解决方法: 在注册 ...
随机推荐
- JAVA会员生日和密码
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import ja ...
- js setInterval 启用&停止
以下面例子为说明: <title></title> <script src="Scripts/jquery-1.4.1-vsdoc.js" type= ...
- [AGC004E] Salvage Robots (DP)
Description 蛤蟆国的领土我们可以抽象为H*W的笼子,在这片蛤土上,有若干个机器人和一个出口,其余都是空地,每次蛤蟆会要求让所有的机器人向某个方向移动一步,当机器人移动到出口时会被蛤蟆活摘出 ...
- Linux服务器之SSH
SSH 1.ssh是安全的加密协议,用于远程连接linux服务器. 2.ssh默认端口是22,安全协议版本ssh2. 3.ssh服务端主要包含两个服务功能ssh远程连接,sftp服务. 4.linux ...
- kernel thread vs user thread
The most important difference is they use different memory, the kernel mode thread can access any ke ...
- 存储过程代码生成器Stored Procedure Generator
原文发布时间为:2010-10-26 -- 来源于本人的百度文章 [由搬家工具导入] Stored Procedure Generator (for SQL Server 2000/2005) htt ...
- SpringTest(一)
SpringMvcTest总结: 最近要做单元测试,所以选择的是SpringTest这个测试框架. 1.准备工作.(导入jar包) 因为使用Maven管理jar包,所以在要做单元测试的模块中的p ...
- 桶排序Bucket sort(转)
补充说明三点 1,桶排序是稳定的 2,桶排序是常见排序里最快的一种,比快排还要快…大多数情况下 3,桶排序非常快,但是同时也非常耗空间,基本上是最耗空间的一种排序算法 我自己的理解哈,可能与网上说的有 ...
- Hadoop-hdfs安装与配置
一.安装要求 安装JDK yum -y install jdk(或手动安装) 设置namenode节点到datanode节点的免密码登陆 a. 本地免密码登录 # ssh loc ...
- java通过反射获取私有的构造方法,及反射擦除泛型数据类型约束
/* * 反射获取私有的构造方法运行 * 不推荐,破坏了程序的安全性,封装性 * 暴力私有 */ public class ReflectDemo4 { public static void main ...