Oracle PL/SQL – NO_DATA_FOUND异常对存储过程性能有坏处理吗?

我正在编写一个存储过程,需要对其进行很多调节。通过C#.NET编码的一般知识,异常可能会损害性能,我一直避免在PL / sql中使用它们。我在这个存储过程中的调理主要围绕着是否存在一个记录,我可以通过两种方法之一进行操作:
SELECT COUNT(*) INTO var WHERE condition;
IF var > 0 THEN
   SELECT NEEDED_FIELD INTO otherVar WHERE condition;
....

-要么-

SELECT NEEDED_FIELD INTO var WHERE condition;
EXCEPTION
WHEN NO_DATA_FOUND
....

第二种情况对我来说似乎更为优雅,因为那时我可以使用NEEDED_FIELD,在第一种情况下,我将不得不在第一条语句中选择该条件。较少的代码但是如果存储过程使用COUNT(*)运行得更快,那么我不介意再打一点点来弥补处理速度。

任何提示?我是否还有另一种可能性?

编辑
我应该提到这一切都已经嵌套在FOR LOOP中。不知道这是否与使用游标有所不同,因为我不认为我可以将光标DECLARE作为FOR LOOP中的选择。

我不会使用显式光标来做到这一点。当可以使用隐式游标时,Steve F.不再建议人们使用显式游标。

count(*)的方法是不安全的。如果另一个会话删除符合count(*)行之后的条件的行,并且在使用select … into的行之前,该代码将抛出一个不会被处理的异常。

从原始帖子的第二个版本没有这个问题,通常是首选。

也就是说,有一个小的开销使用异常,如果你100%肯定数据不会改变,你可以使用计数(*),但我建议反对它。

我在32位Windows上的Oracle 10.2.0.1上运行了这些基准测试。我只是看着经过的时间。还有其他测试线束可以提供更多的细节(例如锁存计数和使用的内存)。

sql>create table t (NEEDED_FIELD number,COND number);

Table created.

sql>insert into t (NEEDED_FIELD,cond) values (1,0);

1 row created.

declare
  otherVar  number;
  cnt number;
begin
  for i in 1 .. 50000 loop
     select count(*) into cnt from t where cond = 1;

     if (cnt = 1) then
       select NEEDED_FIELD INTO otherVar from t where cond = 1;
     else
       otherVar := 0;
     end if;
   end loop;
end;
/

PL/sql procedure successfully completed.

Elapsed: 00:00:02.70

declare
  otherVar  number;
begin
  for i in 1 .. 50000 loop
     begin
       select NEEDED_FIELD INTO otherVar from t where cond = 1;
     exception
       when no_data_found then
         otherVar := 0;
     end;
   end loop;
end;
/

PL/sql procedure successfully completed.

Elapsed: 00:00:03.06

相关文章

Java Oracle 结果集是Java语言中处理数据库查询结果的一种方...
Java AES和Oracle AES是现代加密技术中最常使用的两种AES加密...
Java是一种广泛应用的编程语言,具备可靠性、安全性、跨平台...
随着移动互联网的发展,抽奖活动成为了营销活动中不可或缺的...
Java和Oracle都是在计算机领域应用非常广泛的技术,他们经常...
Java 是一门非常流行的编程语言,它可以运行于各种操作系统上...