Sql 返回的函数没有值
这就是我设计的功能。它得到了成功的遵守Sql 返回的函数没有值,sql,oracle,plsql,Sql,Oracle,Plsql,这就是我设计的功能。它得到了成功的遵守 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;
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
运行此代码时可能出现异常的原因之一是:如果select into没有返回值,则会出现异常,即nu处理的异常 即使在函数的末尾有一个返回NULL,但仍然需要捕获可能发生的所有异常 您需要关注的领域是:
SELECT id, name INTO v_id, v_name from emp_new where id=p_id;
用Begin。。。当找不到数据时出现异常。。。结束代码>块
此外,如果您违反了表上的某些约束,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;
运行此代码时可能出现异常的原因之一是:如果select into没有返回值,则会出现异常,即nu处理的异常
即使在函数的末尾有一个返回NULL,但仍然需要捕获可能发生的所有异常
您需要关注的领域是:
SELECT id, name INTO v_id, v_name from emp_new where id=p_id;
用Begin。。。当找不到数据时出现异常。。。结束代码>块
此外,如果您违反了表上的某些约束,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;
当执行流到达(第22行附近)时,必须返回一个值
在这种情况下,函数不会返回调用者期望的值,因此会出现错误
您可以指示PL/SQL编译器使用
ALTER SESSION SET PLSQL_WARNINGS='ENABLE:ALL'编译之前的代码>。当执行流到达(第22行附近)时,必须返回一个值
在这种情况下,函数不会返回调用者期望的值,因此会出现错误
您可以指示PL/SQL编译器使用
ALTER SESSION SET PLSQL_WARNINGS='ENABLE:ALL'编译前进行编码。函数必须始终返回正确数据类型的值。否则,它将抛出以下错误:
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.
阅读
数据库版本:11.2.0.2.0
让我们看看此错误的各种场景:
函数体中没有RETURN语句,也没有异常处理程序(最愚蠢的方式):
现在,在上面的代码中,数学逻辑是正确的,因此没有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
这很明显,不是吗
异常处理程序中没有返回语句(最常见的错误):
底线是:
- 函数必须始终返回正确数据类型的值,无论是从主体还是从异常返回
- 我们必须处理错误,而不仅仅是返回垃圾。我们必须引发/记录错误并对其进行处理,对错误采取措施,以便底层流程不会受到影响
- 最后,不要忘记,当其他人为空时会出现异常;–>它本身就是代码中的一个bug,等待机会破解代码
函数必须始终返回正确数据类型的值。否则,它将抛出以下错误:
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.
阅读
数据库版本:11.2.0.2.0
让我们看看此错误的各种场景:
函数体中没有RETURN语句,也没有异常处理程序(最愚蠢的方式):
现在,在上面的代码中,数学逻辑是正确的,因此没有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
这很明显,不是吗
- 异常处理程序中没有返回语句(最常见的错误):
底线是:
- 函数必须始终返回正确数据类型的值,无论是从主体还是从异常返回
- 我们必须处理错误,而不仅仅是返回垃圾。我们必须引发/记录错误并对其进行处理,对错误采取措施,以便底层流程不会受到影响
- 最后,不要忘记,当其他人为空时会出现异常;–>它本身就是代码中的一个bug,等待机会破解代码
这不应该成功编译,当没有找到数据时,有一个额外的括号要添加,并检查函数是否达到此异常。如果,它也缺少一个结尾,这一点很重要;如果它在最后一个返回null
之后,则可能会导致此错误,尽管它看起来应该在选择之后。请向我们展示您实际的、成功编译的函数。另外,如果您只返回null,为什么这是一个函数?为什么不把它变成一个过程?@AlexPoole在最后一个if循环中我提到了insert语句,它不应该成功编译,当没有找到数据时,有一个额外的括号来添加,然后检查函数是否达到此异常。如果,它还缺少一个结束,并且在哪里匹配很重要;如果它在最后一个返回null
之后,则可能会导致此错误,尽管它看起来应该在选择之后。请向我们展示您实际的、已成功编译的函数。另外,如果您只返回null,为什么这是一个函数?为什么不将其设置为一个过程?@AlexPoole在最后一个if循环中,我提到了insert语句未经处理