oracle - no_data_found - ora-06512
¿Por qué no_data_found ORA-01403 es una excepción en Oracle? (6)
Si la instrucción SELECT INTO no devuelve al menos una fila, se lanza ORA-01403.
Para todos los demás DBMS, sé que esto es normal en un SELECT. Solo Oracle trata un SELECT INTO de esta manera.
CREATE OR REPLACE PROCEDURE no_data_proc IS
dummy dual.dummy%TYPE;
BEGIN
BEGIN
SELECT dummy
INTO dummy
FROM dual
WHERE dummy = ''Y'';
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line(''Why is this needed?'');
END;
END no_data_proc;
¿Por qué?
En mi opinión no necesitas realmente esta excepción. Es demasiado sobrecarga. A veces es útil, pero tienes que escribir todo un bloque BEGIN, EXCEPTION, WHEN, END.
¿Hay alguna razón esencial que no veo?
El bloque de excepción no es necesario , puede usarlo o no, según el contexto.
Aquí está ignorando activamente la excepción (el procedimiento volverá con éxito), pero la mayoría de las veces, si está haciendo un SELECT INTO, quiere que falle si no devuelve una fila, considere:
PROCEDURE update_employee_salary (p_empno) IS
l_salary NUMBER;
BEGIN
SELECT sal INTO l_salary FROM emp WHERE empno = p_empno FOR UPDATE;
/* do something with emp data */
END;
Aquí quiero que mi función falle si se llama con un empno
que no existe en la tabla EMP. Podría detectar la excepción para generar un mensaje de error significativo (con raise_application_error
) pero la mayoría de las veces estoy contento con el ORA-01403.
En general, las únicas excepciones que debe capturar son las excepciones esperadas (es decir, este no debe ser el estándar para capturar todo el ORA-01403, o todas las excepciones correspondientes).
Pero todavía tenemos que responder a la pregunta de "por qué se lanza una excepción en el caso de que un SELECT no tenga datos para recuperar".
Creo que esto se hace porque es una situación común que de otra manera podría pasarse por alto. Escribir un código como si siempre esperara encontrar datos es algo común, y si tuviéramos que realizar verificaciones de error como
SELECT <something...>
IF SQLCODE = 100 THEN -- No data found
<no-data handler>
END IF
Es probable que, en mi humilde opinión, la comprobación de SQLCODE = 100 se omita con frecuencia. Al tener una excepción, le subieron los rams a la nariz que A) se produjo una condición importante (no se encontraron datos), y B) NO SE HIZO NINGUNA PERLIGENCIA PARA ESTO. La OMI que tiene el motor PL / SQL genera una excepción es mejor que que el programa continúe alegremente en su camino bajo el supuesto de que los datos se recuperaron cuando, de hecho, no fue así, lo que puede llevar a todo tipo de problemas diferentes.
Comparte y Disfruta.
Porque está haciendo SELECT INTO que requiere exactamente una fila (más filas también sería un error).
Si puede tener una o ninguna fila, puede usar un cursor.
No es tarea de la base de datos decidir por usted que una fila que falta no es un error, y simplemente establezca el valor en nulo.
Porque no está claro qué debería hacer el motor PL / SQL, ¿debería salir del bloque? ¿Debería presionar con NULL en la variable? ¿Qué sucede si en el siguiente bloque intenta insertar eso en una columna NO NULA, cómo debería informar la ubicación del error? Hacer que sea una excepción te obliga a ser explícito al respecto.
Puede intentar usar MIN para evitar el uso de la cláusula EXCEPTION.
SELECT MIN(dummy)
INTO dummy
FROM dual
WHERE dummy = ''Y'';
entonces la variable dummy será NULL
También puede utilizar las funciones sql MAX o MIN . Si no se devuelve ninguna fila, estas funciones devolverán un valor NULL .
Por ejemplo: seleccione MAX (columna1) en la variable de la tabla donde columna1 = ''Valor'';
La función MAX devolverá el valor máximo o, si no se devuelve ninguna fila, devolverá NULL.