7
SELECT Value1 INTO lValue
FROM   Table1
WHERE  Field1 = lTempValue;

当匹配为真时,这工作正常。但如果匹配不正确,我会收到错误消息。

ORA-01403: no data found

理想情况下,这对我来说很好,因为我接下来要检查该值是否高于 0,如果是,则在插入查询中使用该值。我不想检查该值,然后必须运行相同的查询来检索它,如果可能的话,我想在一个查询中进行,但我不知道这是如何完成的。

如果有一个值,那么我希望该值进入 lValue。如果没有值,那么我希望 0 进入 lValue。有人有什么想法吗?我只做了一个快速的谷歌检查,但它干涸了。想我会在寻找的时候发布这个。谢谢您的帮助。

4

5 回答 5

16

通常,您只需捕获异常

BEGIN
  SELECT value1
    INTO lValue
    FROM table1
   WHERE field1 = lTempValue;
EXCEPTION
  WHEN no_data_found
  THEN
    lvalue := 0;
END;

NVL您可以通过使用和聚合函数(MIN或)编写更少的代码,MAX但这往往不太明显(例如,请注意,这些答案必须修改几次)。它要求任何追随你的人暂停片刻,以了解你在做什么(以及你是否做得正确)。一个简单的嵌套 PL/SQL 块非常常见且不言自明。

然而,不仅如此,它并没有隐藏由于重复行导致的错误。如果您碰巧在table1where field1is中有两行,则lTempValue仅捕获no_data_found异常会导致意外too_many_rows传播到调用者的异常。由于您不希望有多行,这正是您想要的行为。使用聚合函数隐藏了这样一个事实,即基础数据存在问题,导致您返回可能不正确的结果,并且无法检测到存在问题。我总是宁愿在出现导致重复行出现时立即得到错误——让我在问题失控之前解决问题——而不是几年后发现我们有数百万个重复行,代码偶尔会返回不正确的结果,并且我们在解决根本原因后进行了大量的数据清理工作。

于 2012-08-22T19:53:47.413 回答
3

作为 Justin Cave 建议的替代方案,您可以稍微重写查询,使其始终返回一行 — 如下所示:

SELECT NVL(Value1, 0) INTO lValue
FROM   Table1
RIGHT
JOIN   dual
ON     Field1 = lTempValue
于 2012-08-22T20:32:37.487 回答
2

似乎每个人都真的过于复杂了,假设你的值不是像记录或 clob 这样的奇怪类型:

SELECT NVL(MIN(Value1), 0) INTO lValue
FROM   Table1
WHERE  Field1 = lTempValue;
于 2012-08-24T19:43:17.317 回答
1

我会把它作为一个游标来做——只是为了安全起见(因为,我不喜欢像BEGIN ....END;我的存储过程中那样杂散的 PLSQL 块的想法),比如

CREATE OR REPLACE .....
...

 CURSOR c_get_val IS
 SELECT Value1 
 FROM   Table1
 WHERE  Field1 = lTempValue;

 lValue    Table1.Value1%TYPE;
 lTempValue  Table1.Table1%TYPE;

进而,

BEGIN
...
....
 /* populate lTempValue */

 OPEN c_get_val;
 FETCH c_get_val INTO lValue;
 if c_get_val%NOTFOUND    --this is where you handle ORA-01403: no data found
 then
   lValue := 0;
   /*or call a function, do some other stuff*/
 end if;
 CLOSE c_get_val; 
...
...
EXCEPTION
  /*do some smart exception handling here*/
END;

关于游标的一些信息,还有更多,还有更多

于 2012-08-23T21:23:43.683 回答
-1
BEGIN
  SELECT value1
    INTO lValue
    FROM table1
   WHERE field1 = lTempValue;
EXCEPTION
  WHEN no_data_found
  THEN
    lvalue := 0;
EXCEPTION
  WHEN too_many_rows
  THEN
    lvalue := 0;
END;
于 2012-08-24T21:04:51.180 回答