SELECT Value1 INTO lValue
FROM Table1
WHERE Field1 = lTempValue;
匹配为true时,此方法正常。但如果匹配不成立,我会收到错误。
ORA-01403: no data found
理想情况下,这对我来说很好,因为我要检查旁边的值是否高于0,如果是,请在插入查询中使用该值。我不想检查值,然后必须运行相同的查询来检索它本质上,如果可能的话,我想在一个查询中执行它,但我无法弄清楚如何完成。
如果有值,那么我希望该值进入lValue。如果没有值,那么我希望0进入lValue。有人有任何想法吗?我只是做了一个快速谷歌检查,但它干了。想看,我会在看的时候发布这个。谢谢你的帮助。
答案 0 :(得分:14)
通常情况下,您只需捕获异常
BEGIN
SELECT value1
INTO lValue
FROM table1
WHERE field1 = lTempValue;
EXCEPTION
WHEN no_data_found
THEN
lvalue := 0;
END;
您可以使用NVL
和聚合函数(MIN
或MAX
)来编写更少的代码,但这往往不太明显(例如,请注意那些答案必须修改几次)。并且它要求跟随你的人暂停片刻以了解你在做什么(以及你是否正确地做到了)。一个简单的嵌套PL / SQL块很常见且非常容易理解。
然而,不仅如此,它不会隐藏由于重复行而导致的错误。如果恰好在table1
field1
lTempValue
no_data_found
中获得两行,则仅捕获too_many_rows
异常会将意外的{{1}}异常传播到调用者。由于您不希望有多行,这正是您想要的行为。使用聚合函数隐藏了以下事实:基础数据存在问题,导致您返回可能不正确的结果,并且无法检测到存在问题。一旦某些东西导致重复的行出现,我总是会发现错误 - 允许我在问题失控之前解决问题 - 而不是多年后发现我们已经有数百万个重复的行,代码偶尔会返回错误的结果,并且在解决根本原因后我们会进行大量的数据清理工作。
答案 1 :(得分:3)
作为Justin Cave的建议的替代方法,您可以稍微重写查询,以便它总是返回一行 - 如下所示:
SELECT NVL(Value1, 0) INTO lValue
FROM Table1
RIGHT
JOIN dual
ON Field1 = lTempValue
答案 2 :(得分:2)
似乎每个人都真的过于复杂,假设你的值不是像记录或clobs这样奇怪的类型:
SELECT NVL(MIN(Value1), 0) INTO lValue
FROM Table1
WHERE Field1 = lTempValue;
答案 3 :(得分: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;
答案 4 :(得分:-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;