因此,我有一个存储过程(下面出于演示目的已对其进行了简化),该存储过程没有通过任何条件,因此也没有在表中插入/传递任何值。我试过将Java传递的varchar / string转换为数字,但是没有任何效果。下面是我的“简化代码”
Create or Replace Procedure SAMPLE(rValue IN VARCHAR)
IS
v_Max value.value%type;
v_forecast value.value%type;
BEGIN
--
SELECT BUFFER_MAX_VALUE
INTO v_MAX
FROM look_up;
--
EXCEPTION
WHEN no_data_found
THEN SELECT 0
INTO v_forecast
FROM DUAL;
--
IF to_Number(rValue) < 0 OR to_Number(rValue) > v_MAX)
THEN
dbms_output.put_line('IF1 Works');
insert into value(value_id, value)
values(1, rValue);
ELSIF rValue is null OR to_Number(rValue) = 0
THEN
dbms_output.put_line('IF1A ONLY Works');
END IF;
ELSE
insert into value(value_id, value)
values(1, v_forecast);
dbms_output.put_line('IF1 ELSE ONLY Works');
END SAMPLE;
我尝试传递以下内容:
BEGIN
SAMPLE('-7');
END;
答案 0 :(得分:1)
据我所知,您想让异常部分捕获查找表中什么都没有的情况。在这种情况下,请设置v_forecast,然后继续。这意味着您需要将select放入其自己的块中。
我还通过设置一个常量来避免多次to_number调用。
我摆脱了双重选择中不必要的选择。
我也非常希望您没有一个名为VALUE的表,该表的一个名为VALUE的列。选择更有意义的名称。
看看它如何为您工作。
CREATE OR REPLACE PROCEDURE sample (rvalue IN VARCHAR2)
IS
c_rvalue CONSTANT NUMBER := rvalue;
v_max VALUE.VALUE%TYPE;
v_forecast VALUE.VALUE%TYPE;
BEGIN
BEGIN
SELECT buffer_max_value INTO v_max FROM look_up;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
v_forecast := 0;
END;
IF c_rvalue < 0 OR c_rvalue > v_max
THEN
DBMS_OUTPUT.put_line ('IF1 Works');
INSERT INTO VALUE (value_id, VALUE)
VALUES (1, rvalue);
ELSIF c_rvalue IS NULL OR c_rvalue = 0
THEN
DBMS_OUTPUT.put_line ('IF1A ONLY Works');
ELSE
INSERT INTO VALUE (value_id, VALUE)
VALUES (1, v_forecast);
DBMS_OUTPUT.put_line ('IF1 ELSE ONLY Works');
END IF;
END sample;
答案 1 :(得分:1)
如果第一个SELECT BUFFER_MAX_VALUE
返回任何内容,则不会执行任何其他操作,因为您将一切绝对放入了EXCEPTION
部分。如果只打算处理该语句,则应将其包含在其自己的BEGIN-END块中,例如
create procedure ...
begin
-- its own begin starts now
begin
select buffer_max_value into v_max
from look_up;
exception
when no_data_found then
-- do something here
end;
-- its own end ends now
-- put the rest of your code here
end;
顺便说一句,LOOK_UP表是否总是不包含行或仅包含一行?因为,正如您所写的SELECT
不包含WHERE
子句,它可能会引发TOO_MANY_ROWS
(您也应该处理)。
您将rValue
声明为VARCHAR2
,然后对其应用TO_NUMBER
。为什么不声明它为NUMBER
?因为,没有什么阻止您将'XYZ'传递给该过程,然后TO_NUMBER
会因INVALID NUMBER
错误而失败。
[编辑:更多异常处理]
EXCEPTION
部分处理该BEGIN-END
块中发生的所有异常,无论您有多少SELECT
条语句。但是,除非您包括一些额外的(简单的)编程,否则您不会知道哪个失败。
请注意,这只是为了显示我的意思;不要使用DBMS_OUTPUT
处理错误(很可能没有人会看到它),很少有您想使用WHEN OTHERS
处理错误。
create procedure ...
l_position number;
begin
l_position := 1;
select ... into ... from ...;
l_position := 2;
select ... into ...
exception
when others then
dbms_output.put_line('Error on position ' || l_position ||' '|| sqlerrm);
raise;
end;