Oracle 为什么在这个过程中我的条件都不满足?

Oracle 为什么在这个过程中我的条件都不满足?,oracle,plsql,Oracle,Plsql,因此,我有一个存储过程(为了演示的目的,下面对其进行了淡化),它不传递任何条件,因此也不向表中插入/传递任何值。我尝试将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

因此,我有一个存储过程(为了演示的目的,下面对其进行了淡化),它不传递任何条件,因此也不向表中插入/传递任何值。我尝试将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;

据我所知,您希望异常部分捕获查找表中没有任何内容的情况。在这种情况下,您可以设置v_forecast,然后继续。这意味着您需要将select放在它自己的块中

我还通过设置一个常量来避免多次拨打电话

我摆脱了不必要的双重选择

我还真的希望您没有一个名为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;
创建或替换过程示例(VARCHAR2中的右值)
是
c_右值常量:=右值;
v_最大值。值%类型;
v_预测值。值%类型;
开始
开始
从查找中选择缓冲区最大值到v最大值;
例外情况
当找不到数据时
然后
v_预测:=0;
结束;
如果c_右值<0或c_右值>v_max
然后
DBMS_OUTPUT.put_line('IF1起作用');
插入值(值\u id,值)
数值(1,右值);
如果c_右值为空或c_右值=0
然后
DBMS_OUTPUT.put_line('IF1A仅起作用');
其他的
插入值(值\u id,值)
数值(1,v_预测);
DBMS_OUTPUT.put_line('IF1 ELSE ONLY Works');
如果结束;
末端样品;

如果第一个
SELECT BUFFER\u MAX\u 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;
顺便问一下,查找表总是不包含行还是只包含一行?因为,当您编写的
SELECT
不包含
WHERE
子句时,它可能会引发
太多行(您也应该处理该行)

您将
rValue
声明为
VARCHAR2
,然后对其应用
。你为什么不把它声明为一个
数字
?因为,没有任何东西可以阻止您传递,例如,“XYZ”到过程,然后
到_NUMBER
将由于
无效编号
错误而失败

[编辑:更多异常处理]

EXCEPTION
部分处理该
BEGIN-END
块中发生的所有异常,无论有多少
SELECT
语句。不过,除非包含一点额外的(简单的)编程,否则您不知道哪一个失败了

请注意,这只是为了说明我的意思;不要使用
DBMS\u输出处理错误(因为,很可能没有人会看到它),而且当其他人使用
时,您很少希望使用
处理错误

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;

什么是
v_Max
?什么是dbms_输出报告(else?)?v_Max只是我为IF比较而导出的值。如果传入的值大于v_Max或小于0,则应打印第一个dbms_输出字符串。不太清楚你在第二个问题中问了什么我是在问这个问题是否会说出“IF1 ELSE ONLY work”?与其他两种情况一样,这两种情况都失败了,只有
ELSE
跳闸,或者根本没有跳闸?但是我的意思是我知道奇怪之处。第一个条件应跳闸,因为右值为-7。根本不打印任何内容。我想知道它是否与异常有关?我能够对异常进行注释,它似乎有效。有没有一种方法可以在不使用异常方法的情况下为这个变量指定一个默认值(这似乎把一切都抛在脑后了)?谢谢@Littlefoot。Java程序正在传递一个字符串,他们无法将其更改为数字(或者干脆拒绝)。假设它们永远不会传入任何非数字字符(我知道这是一种非常时髦的方式)。如果我有多个“select into”语句(在我的实际代码中,我有多个变量),那么即使我将其放在所有“select intos”之后,异常是否也会应用于所有变量?或者我需要为每个变量加一个?我猜是前者,但只是确定一下。我在我的信息中添加了更多的信息;看一看,谢谢你。那么,我是否遵循与您的第一段代码相同的格式?(我在所有变量定义之前和之后(分别)开始/结束的地方)?是的,如果你想分别处理它们的话。好吧,现在已经快午夜了,所以我的大脑不能在高水平上工作,但是-我想说不是,没有捷径。一个“常规”异常部分处理整个BEGIN-END块的所有错误,但是-如果要单独处理每个SELECT,则必须将每个SELECT包含在其自己的BEGIN-EXCEPTION-END中。
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;