这是我设计的功能。它顺利完成了
CREATE OR REPLACE FUNCTION "F_CHECK"
(
p_id IN VARCHAR2
p_name IN VARCHAR2)RETURN VARCHAR2
is
v_id VARCHAR2;
v_name VARCHAR2;
cnt pls_integer;
BEGIN
IF id IS NULL THEN
RETURN NULL;
END IF;
SELECT COUNT(*) INTO cnt from emp_new where id = p_id;
IF (cnt > 0) THEN
SELECT id, name INTO v_id, v_name from emp_new where id=p_id;
IF (v_id is null and p_id is null and v_name is null and p_name is null) THEN
return NULL;
ELSE
IF (v_name =trunc(p_name)) then
return NULL;
else
insert into employees values(p_id,p_name,sysdate);
end if;
end if;
end if;
exception
when DUP_VAL_ON_INDEX THEN
raise application error (-20001, 'NAME EXISTS UNDER DIFFERENT ID');
END F_CHECK;
但是当我执行函数
时,我没有得到预期的结果select F_CHECK(1,1) from dual;
错误我得到的是:
SQL EEROR: ORA-06503: PL/SQL : FUNCTION RETURNED WITHOUT VALUE
答案 0 :(得分:2)
执行流程到达时(第22行)
,您必须返回一个值...
else
insert into employees values(p_id,p_name,sysdate);
end if;
...
在这种情况下,函数不会返回调用者期望的值,因此会出错。
您可以指示PL / SQL编译器向您发出有关此类代码(以及其他问题)的警告
在编译之前ALTER SESSION SET PLSQL_WARNINGS='ENABLE:ALL';
。
答案 1 :(得分:1)
运行此代码时可能会导致异常的一个原因是:如果您的select into没有返回值,您将获得异常,一个nu处理异常
即使你在函数的末尾有一个返回NULL,但你仍然需要捕获可能发生的所有异常
您需要照顾的区域是:
SELECT id, name INTO v_id, v_name from emp_new where id=p_id;
围绕Begin ... EXCEPTION WHEN NO_DATA_FOUND THEN ... END;
阻止
此外,如果您违反了表上的某些约束,您的insert语句可能会导致异常,因此您可能还需要处理它
以下是您的更新代码,以及有关额外括号的固定代码
<强>被修改强>
CREATE OR REPLACE FUNCTION F_CHECK
(
P_ID EMP_NEW.ID%TYPE,
P_NAME EMP_NEW.NAME%TYPE
)
RETURN VARCHAR2 IS
V_ID EMP_NEW.ID%TYPE;
V_NAME EMP_NEW.NAME%TYPE;
CNT NUMBER;
BEGIN
--IF ID IS NULL THEN
-- What is ID ?? is it P_ID
--Changed below
IF P_ID IS NULL THEN
RETURN 'Error: Add Value For Id';
END IF;
IF P_NAME IS NULL THEN
RETURN 'Error: Add Value For Name';
END IF;
SELECT
COUNT(*) INTO CNT FROM EMPLOYEES
WHERE ID = P_ID;
IF (CNT > 0) THEN
SELECT
ID, NAME INTO V_ID, V_NAME
FROM
EMP_NEW
WHERE
ID=P_ID;
----------------------------------------------------------------------------------------
--IF V_ID IS NULL AND P_ID IS NULL AND V_NAME IS NULL AND P_NAME IS NULL THEN
--The code above will always evaluate to False because P_ID at this stage is not null!
--Also, if P_Name must have a value, check it at the begining along with the ID, not here
----------------------------------------------------------------------------------------
IF V_ID IS NULL AND V_NAME IS NULL THEN
RETURN 'Error: Not found details';
ELSE
--Details are found
IF (V_NAME = TRUNC(P_NAME)) THEN
RETURN 'Name already assigned to this id';
ELSE --Its a new name, add it
INSERT INTO EMPLOYEES VALUES(P_ID,P_NAME,SYSDATE);
--Make sure your columns are only three and in the correct order as the Values specified
END IF;
END IF;
END IF;
RETURN 'Ok, added';
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
raise application error (-20001, 'NAME EXISTS UNDER DIFFERENT ID');
END F_CHECK;
答案 2 :(得分:1)
函数必须始终返回正确数据类型的值。否则,它会抛出以下错误:
ORA-06503: PL/SQL: Function returned without value
Cause: A call to PL/SQL function completed, but no RETURN statement was executed.
Action: Rewrite PL/SQL function, making sure that it always returns a value of a proper type.
阅读ORA-06503: PL/SQL: Function returned without value
数据库版本:11.2.0.2.0
让我们看看这个错误的各种情况:
在函数体中没有 RETURN 语句且没有异常处理程序(最愚蠢的方式):
SQL> set serveroutput on
SQL> CREATE OR REPLACE FUNCTION f_test(i_val NUMBER)
2 RETURN NUMBER AS
3 o_val NUMBER;
4 BEGIN
5 SELECT 100 / i_val
6 INTO o_val
7 FROM DUAL;
8 END;
9 /
Function created
SQL> select f_test(100) from dual;
select f_test(100) from dual
ORA-06503: PL/SQL: Function returned without value
ORA-06512: at "F_TEST", line 8
现在,在上面的代码中,数学逻辑是正确的,因此没有SQL错误来覆盖PL / SQL错误。让我们看看ORA-01476如何覆盖ORA-06503错误。
SQL> CREATE OR REPLACE FUNCTION f_test(i_val NUMBER)
2 RETURN NUMBER AS
3 o_val NUMBER;
4 BEGIN
5 SELECT 100 / i_val
6 INTO o_val
7 FROM DUAL;
8 END;
9 /
Function created
SQL> select f_test(0) from dual;
select f_test(0) from dual
ORA-01476: divisor is equal to zero
ORA-06512: at "F_TEST", line 5
嗯,这很明显,不是吗?
SQL> CREATE OR REPLACE FUNCTION f_test(i_val NUMBER) 2 RETURN NUMBER AS 3 o_val NUMBER; 4 BEGIN 5 SELECT 100 / i_val 6 INTO o_val 7 FROM DUAL; 8 9 RETURN o_val; 10 11 EXCEPTION 12 WHEN OTHERS THEN 13 NULL; 14 END; 15 / Function created SQL> select f_test(0) from dual; select f_test(0) from dual ORA-06503: PL/SQL: Function returned without value ORA-06512: at "F_TEST", line 14
现在让我们在所需的位置放置一个RETURN语句,代码应该可以正常工作而不会出现任何错误:
SQL> CREATE OR REPLACE FUNCTION f_test(i_val NUMBER)
2 RETURN NUMBER AS
3 o_val NUMBER;
4 BEGIN
5 SELECT 100 / i_val
6 INTO o_val
7 FROM DUAL;
8
9 RETURN o_val;
10
11 EXCEPTION
12 WHEN OTHERS THEN
13 DBMS_OUTPUT.PUT_LINE('Came inside Exception handler');
14 RETURN 0;
15 END;
16 /
Function created
SQL> select f_test(0) from dual;
F_TEST(0)
0
Came inside Exception handler
底线是: