为什么我的“选择变量”语句使存储过程没有在表中插入任何内容?

时间:2018-07-30 17:49:38

标签: sql oracle plsql

因此,我目前有一个存储过程,可以将存储过程简单地插入到名为“ VALUE”的表中。我测试了此片段,并调用了以下过程:

Create Or Replace Procedure TEST_PROCEDURE(rValue_tx IN VARCHAR, rData_Type IN VARCHAR)
IS
BEGIN
IF rValue_Tx >= 0 THEN
                IF rData_Type in ('TEST', 'REAL')
                THEN
                Insert into Value (VALUE_ID, VALUE_TX, CREATE_DT)
                VALUES (1, rValue_tx, SYSDATE);
END IF;
END IF;
END TEST_PROCEDURE;

但是;当我尝试将数字插入变量时(增加了另一层复杂性),没有任何插入。下面是添加了另一层复杂性的代码:

Create Or Replace Procedure TEST_PROCEDURE_NEW(rValue_tx IN VARCHAR, rData_Type IN VARCHAR)
IS
v_MAX_historic_value value.value_tx%type;
BEGIN
---
SELECT MAX(BUFFER_MAX)
  INTO v_MAX_Historic_Value
  FROM max_look_up;
EXCEPTION
     WHEN no_data_found
     THEN SELECT 0
            INTO v_MAX_Historic_Value
            FROM DUAL;
---
IF rValue_Tx >= 0 
THEN
                IF rData_Type in ('TEST', 'REAL')
                THEN
                Insert into Value (VALUE_ID, VALUE_TX, CREATE_DT)
                VALUES (null, rValue_tx, SYSDATE);
END IF;
END IF;
END TEST_PROCEDURE_NEW;

我确定我缺少PL / SQL的一些基本规则,但是似乎无法弄清楚哪个规则。似乎是EXCEPTION导致该过程没有在VALUE表中插入任何行,但是我不确定为什么(或有更好的方法来做到这一点?)...任何帮助将不胜感激: (

代替使用EXCEPTION;当max_look_up中没有数据并且没有任何结果/空值返回时,有没有更好的方法让我处理?

3 个答案:

答案 0 :(得分:2)

通过适当的代码缩进,很明显,除第一个SELECT语句外,所有代码都在异常处理程序中。

但是,SELECT MAX(...)将始终返回数据,并且永远不会触发NO_DATA_FOUND异常。因此,永远不会达到INSERT语句。

Create Or Replace Procedure TEST_PROCEDURE_NEW(rValue_tx IN VARCHAR, rData_Type IN VARCHAR)
IS
    v_MAX_historic_value value.value_tx%type;
BEGIN

    SELECT MAX(BUFFER_MAX)
        INTO v_MAX_Historic_Value
        FROM max_look_up;

EXCEPTION
    WHEN no_data_found
    THEN
        SELECT 0
            INTO v_MAX_Historic_Value
            FROM DUAL;

        IF rValue_Tx >= 0 THEN
            IF rData_Type in ('TEST', 'REAL') THEN
                Insert into Value (VALUE_ID, VALUE_TX, CREATE_DT)
                    VALUES (null, rValue_tx, SYSDATE);
            END IF;
        END IF;
END TEST_PROCEDURE_NEW;

您可能想要的是将代码移出异常处理程序。为此,您可以在第一个BEGIN语句和异常处理代码周围引入另外一对END / SELECT。但是,由于永远不会触发异常,因此完全删除异常处理会更容易。相反,您应该检查NULL,因为如果没有选择任何行,则MAX(...)返回NULL

Create Or Replace Procedure TEST_PROCEDURE_NEW(rValue_tx IN VARCHAR, rData_Type IN VARCHAR)
IS
    v_MAX_historic_value value.value_tx%type;
BEGIN

    SELECT MAX(BUFFER_MAX)
        INTO v_MAX_Historic_Value
        FROM max_look_up;

    IF v_MAX_Historic_Value IS NULL THEN
        v_MAX_Historic_Value := 0;
    END IF;

    ...


    IF rValue_Tx >= 0 THEN
        IF rData_Type in ('TEST', 'REAL') THEN
            Insert into Value (VALUE_ID, VALUE_TX, CREATE_DT)
                VALUES (null, rValue_tx, SYSDATE);
        END IF;
    END IF;
END TEST_PROCEDURE_NEW;

答案 1 :(得分:1)

经过进一步的研究,我找到了问题的另一种解决方案(不使用异常)(如果我错了,请纠正我):

Create Or Replace Procedure TEST_PROCEDURE_NEW(rValue_tx IN VARCHAR, rData_Type IN VARCHAR)
IS
v_MAX_historic_value value.value_tx%type;
BEGIN

with EXEC as
(select 0 buffer_max
   from dual
  UNION
 select MAX(BUFFER_MAX)
    FROM max_look_up) select max(buffer_max) into v_MAX_Historic_Value from EXEC;
IF rValue_Tx >= 0 THEN
    IF rData_Type in ('TEST', 'REAL') THEN
        Insert into Value (VALUE_ID, VALUE_TX, CREATE_DT)
            VALUES (null, rValue_tx, SYSDATE);
        END IF;
    END IF;
END TEST_PROCEDURE_NEW;

答案 2 :(得分:1)

我认为您只是将 Exception 关键字放错了位置,请尝试以下操作:

CREATE OR REPLACE PROCEDURE TEST_PROCEDURE_NEW (
                                                RVALUE_TX    IN VARCHAR,
                                                RDATA_TYPE   IN VARCHAR
                                               )
IS
   V_MAX_HISTORIC_VALUE   VALUE.VALUE_TX%TYPE;
BEGIN
   ---
   BEGIN
      SELECT MAX (BUFFER_MAX) INTO V_MAX_HISTORIC_VALUE FROM MAX_LOOK_UP;
   EXCEPTION
      WHEN NO_DATA_FOUND
      THEN
         SELECT 0 INTO V_MAX_HISTORIC_VALUE FROM DUAL;
   END;

   ---
   IF RVALUE_TX >= 0
   THEN
      IF RDATA_TYPE IN ('TEST', 'REAL')
      THEN
         INSERT INTO VALUE (VALUE_ID, VALUE_TX, CREATE_DT)
         VALUES (NULL, RVALUE_TX, SYSDATE);
      END IF;
   END IF;
END TEST_PROCEDURE_NEW;