Obecnie mam przekładowaną procedurę, która wykonuje prostą wkładkę do tabeli o nazwie "Wartość". Przetestowałem ten utwór i zwany poniższą procedurą:

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;

Jednak; Kiedy próbuję wstawić numer do zmiennej (dodanie innej warstwy złożoności), nic nie zostanie wstawione. Poniżej znajduje się kod z inną warstwą złożoności dodanej do niej:

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;

Jestem pewien, że tęsknię za jakąś fundamentalną zasadę PL / SQL, ale nie można wymyślić, która zasada. Wydaje się, że jest to wyjątek, który powoduje, że procedura nie wstawia żadnych wierszy do tabeli wartości, ale nie jestem dokładnie pewien, dlaczego (lub jest lepszy sposób na to zrobić?) ... Każda pomoc byłaby bardzo doceniana: (

Zamiast używać wyjątku; Czy jest dla mnie lepszy sposób, gdy nie ma danych w max_look_up i nic / null zostaje zwrócony w rezultacie?

1
John Wick 30 lipiec 2018, 20:49

3 odpowiedzi

Najlepsza odpowiedź

Myślę, że tylko źle się usprawiedliwiony wyjątek , spróbuj tego:

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;
1
hmmftg 31 lipiec 2018, 10:16

Dzięki właściwym wcięciu kodu jest oczywiste, że cały kod, z wyjątkiem pierwszej instrukcji SELECT, znajduje się w programie obsługi wyjątków.

Jednak SELECT MAX(...) zawsze zwraca dane i nigdy nie wywołać wyjątku NO_DATA_FOUND. Dlatego oświadczenie INSERT nigdy nie jest osiągane.

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;

To, co prawdopodobnie chcesz przenieść kod z przewodnika o wyjątku. Zrobiłbyś to, wprowadzając kolejną parę BEGIN / END wokół pierwszego oświadczenia {x2}} i kod obsługi wyjątku. Jednakże, ponieważ wyjątek nigdy nie jest wyzwalany, łatwiej jest całkowicie usunąć obsługę wyjątku. Zamiast tego powinieneś sprawdzić NULL jako MAX(...) zwraca NULL Jeśli nie wybrano żadnych wierszy.

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;
2
Codo 30 lipiec 2018, 19:21

Po kilku dalszych badań znalazłem alternatywne rozwiązanie (bez użycia wyjątków) do mojego pytania (proszę mnie poprawić, jeśli się mylę):

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;
1
John Wick 30 lipiec 2018, 19:30