Tôi nhận thấy hành vi lạ của NO_DATA_FOUND
ngoại lệ khi được ném từ hàm được sử dụng trong PLSQL.Trường hợp ngoại lệ NO_DATA_FOUND không được ném khi được sử dụng trong SELECT INTO
Ngắn câu chuyện - nó truyền từ chức năng khi sử dụng chuyển nhượng và không lan truyền (hoặc được xử lý âm thầm ở đâu đó ở giữa) khi được sử dụng trong SELECT INTO
.
Vì vậy, chức năng trao test_me
ném NO_DATA_FOUND
ngoại lệ, khi viện dẫn như:
v_x := test_me(p_pk);
Nó ném một ngoại lệ, trong khi khi viện dẫn như:
SELECT test_me(p_pk) INTO v_x FROM dual;
nó không ném ngoại lệ. Điều này không xảy ra với các trường hợp ngoại lệ khác. Dưới đây bạn có thể tìm thấy các ví dụ thử nghiệm của tôi.
Ai đó có thể giải thích cho tôi về hành vi này?
set serveroutput on;
CREATE OR REPLACE FUNCTION test_me(p_pk NUMBER) RETURN NVARCHAR2
IS
v_ret NVARCHAR2(50 CHAR);
BEGIN
BEGIN
SELECT 'PYK' INTO v_ret FROM dual WHERE 1 = 1/p_pk;
EXCEPTION WHEN NO_DATA_FOUND THEN
dbms_output.put_line(chr(9)||chr(9)||chr(9)||' (test_me NO_DATA_FOUND handled and rerised)');
RAISE;
END;
RETURN v_ret;
END;
/
DECLARE
v_x NVARCHAR2(500 CHAR);
v_pk NUMBER;
PROCEDURE test_example(p_pk NUMBER)
IS
BEGIN
BEGIN
dbms_output.put_line(chr(9)||chr(9)||'Test case 1: Select into.');
SELECT test_me(p_pk) INTO v_x FROM dual;
dbms_output.put_line(chr(9)||chr(9)||'Success: '||NVL(v_x,'NULL RETURNED'));
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line(chr(9)||chr(9)||'Failure: NO_DATA_FOUND detected');
WHEN OTHERS THEN
dbms_output.put_line(chr(9)||chr(9)||'Failure: '||SQLCODE||' detected');
END;
dbms_output.put_line(' ');
BEGIN
dbms_output.put_line(chr(9)||chr(9)||'Test case 2: Assignment.');
v_x := test_me(p_pk);
dbms_output.put_line(chr(9)||chr(9)||'Success: '||NVL(v_x,'NULL RETURNED'));
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line(chr(9)||chr(9)||'Failure: NO_DATA_FOUND detected');
WHEN OTHERS THEN
dbms_output.put_line(chr(9)||chr(9)||'Failure: '||SQLCODE||' detected');
END;
END;
BEGIN
dbms_output.put_line('START');
dbms_output.put_line(' ');
dbms_output.put_line(chr(9)||'Example 1: Function throws some exception, both cases throws exception, everything is working as expected.');
test_example(0);
dbms_output.put_line(' ');
dbms_output.put_line(chr(9)||'Example 2: Query returns row, there is no exceptions, everything is working as expected.');
test_example(1);
dbms_output.put_line(' ');
dbms_output.put_line(chr(9)||'Example 3: Query inside function throws NO_DATA_FOUND, strange things happen - one case is throwing exception, the other is not.');
test_example(2);
dbms_output.put_line(' ');
dbms_output.put_line('END');
END;
/
DROP FUNCTION test_me;
Ví dụ 1 không thành công trên 'ORA-01476: ước số bằng 0 ngoại lệ. – MT0
Và nó có. :) Tôi đã thêm mô tả rõ ràng hơn về các ví dụ. –