Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
调用PL/SQL函数时出错_Sql_Oracle_Plsql - Fatal编程技术网

调用PL/SQL函数时出错

调用PL/SQL函数时出错,sql,oracle,plsql,Sql,Oracle,Plsql,我已经创建了一个PL/SQL函数,该函数应该在我前面创建的new_dept_new sequence的帮助下向表中添加给定数量的记录。该函数已成功编译。但调用函数时出现错误: BEGIN dbms_output.put_line(myfunction3(3, 'OPERATIONS', 'NEW YORK')); END; Error report - ORA-06503: PL/SQL: Function returned without value 职能: CREATE OR REPLA

我已经创建了一个PL/SQL函数,该函数应该在我前面创建的new_dept_new sequence的帮助下向表中添加给定数量的记录。该函数已成功编译。但调用函数时出现错误:

BEGIN
dbms_output.put_line(myfunction3(3, 'OPERATIONS', 'NEW YORK'));
END;

Error report -
ORA-06503: PL/SQL: Function returned without value
职能:

CREATE OR REPLACE FUNCTION myfunction3(
records_count_in IN NUMBER, dept_name_in IN dept.dname%TYPE, loc_name_in IN dept.loc%TYPE)

RETURN INTERVAL DAY TO SECOND
IS 
thestart  TIMESTAMP := CURRENT_TIMESTAMP;
stopwatch INTERVAL DAY TO SECOND;
records_count NUMBER := records_count_in;
dept_name dept.dname%TYPE := dept_name_in;
loc_name dept.loc%TYPE := loc_name_in;

BEGIN
    FOR i IN 1..records_count LOOP
        INSERT INTO dept VALUES(new_dept_new.nextval, dept_name || TO_CHAR(new_dept_new.currval), loc_name || TO_CHAR(new_dept_new.currval));
COMMIT;
END LOOP;
    stopwatch := CURRENT_TIMESTAMP - thestart;
    DBMS_OUTPUT.PUT_LINE('Time for processing function: ');
RETURN stopwatch;
EXCEPTION WHEN OTHERS 
    THEN dbms_output.put_line('ERROR Processing Request for Department: ' || dept_name_in);
END;
为什么函数返回时没有值

编辑: 收到评论反馈后,我编辑了函数,现在将值插入表中,并返回时间戳值。我还希望在插入0行时引发应用程序错误

因此,我做了以下工作:

CREATE OR REPLACE FUNCTION myfunction3(
records_count_in IN NUMBER, dept_name_in IN dept.dname%TYPE, loc_name_in IN dept.loc%TYPE)

RETURN INTERVAL DAY TO SECOND
IS 
thestart  TIMESTAMP := CURRENT_TIMESTAMP;
stopwatch INTERVAL DAY TO SECOND;
records_count NUMBER := records_count_in;
dept_name dept.dname%TYPE := dept_name_in;
loc_name dept.loc%TYPE := loc_name_in;

BEGIN
    FOR i IN 1..records_count LOOP
        INSERT INTO dept (deptno, dname, loc) 
        VALUES(new_dept_new.nextval, dept_name || TO_CHAR(new_dept_new.currval), loc_name || TO_CHAR(new_dept_new.currval));
    IF SQL%ROWCOUNT = 0 THEN
    raise_application_error (-20001, 'ERROR Processing Request for Department: ' || dept_name_in);
    END IF;
END LOOP;
    stopwatch := CURRENT_TIMESTAMP - thestart;
    DBMS_OUTPUT.PUT_LINE('Time for processing function: ');
RETURN stopwatch;
END;
但是,如果我像这样调用函数,并且插入了零条记录,我就不会收到自定义错误消息

开始dbms_output.put_linemyfunction30,'开发操作','纽约';结束


我怎样才能解决这个问题

函数中存在一些异常,导致函数遇到异常块。异常块中没有返回语句,因此出现错误。添加RAISE语句以查看导致异常的原因。

除了异常块之外,您的函数似乎没有任何问题。我能够用您使用的表名和列名模拟该场景,它工作得非常好。若有其他问题,比如缺少表,那个么它就不会为您编译。因此,它失败的唯一原因是您的insert语句。它可以是违反约束、值的长度超过列长度限制等

您可以通过添加raise语句对异常块进行轻微更改。这将帮助您识别调用程序中的实际错误

EXCEPTION WHEN OTHERS 
    THEN dbms_output.put_line('ERROR Processing Request for Department: ' || dept_name_in);
RAISE;
此外,决不要像这样运行insert语句

INSERT INTO dept VALUES (...)
这不是一个好的编码实践,很难知道它将插入哪个顺序,尤其是当有许多列时

总是明确地提到这些列

INSERT INTO dept ( dept_id,dname,loc)  VALUES (..,..,..);

更好的问题是,为什么我的函数编译成功,而它显然是不正确的?显然,因为不返回值的函数不可能是正确的。时期更好的问题的答案是例外块。你不应该,永远不要用别人的话。结果是,不管函数有什么错误,都会被忽略,编译器会说OK,编译成功,而实际上函数可能充满了错误。不要难过;很多人都做了你做过的事,但这并不能减少错误。@mathguy谢谢,我理解我的错误。我对函数进行了编辑,以便将值插入表中。此外,我还添加了IF SQL%ROWCOUNT=0,然后引发应用程序错误-20001,“部门错误处理请求:”| |部门名称|in;如果结束;右上方的结束循环;但是,如果我像这样调用函数,并且插入了零条记录,我就不会收到自定义错误消息。开始dbms_output.put_linemyfunction30,'开发操作','纽约';终止在0中传递记录如何计数会引发应用程序错误。它根本不会进入循环。这不能用这种方式来模拟。仅当未插入任何记录时,SQL%ROWCOUNT才会设置为0。我已根据您的注释编辑了INSERT语句,现在这些值已插入到表中。但我还希望在插入0行时引发应用程序错误。因此,我添加了IF-SQL%ROWCOUNT=0,然后引发应用程序错误-20001,“部门错误处理请求:”| |部门名称|in;如果结束;右上方的结束循环;但是,如果我像这样调用函数,并且插入了零条记录,我就不会收到自定义错误消息。开始dbms_output.put_linemyfunction30,'开发操作','纽约';终止我怎样才能解决这个问题?