我的PL / SQL程序有问题。我在一个包中声明了一个公共过程,我想在第一个过程中调用另一个过程(私有)。
PROCEDURE show_notesforstudent (number_id IN number) as
...
DBMS_OUTPUT.PUT_LINE('The notes for the student with number_id X are: '|| Y);
DBMS_OUTPUT.PUT_LINE('here is the call for the private procedure');
erase_student(number_id);
END;
此代码是一般示例,我的代码更大,我无法将其全部放在此处。这里只是主要的想法。 对于此次通话,我面临此错误:"错误(31,5):PLS-00313:' erase_student'未在此范围内宣布"。
erase_student程序的实现是:
PROCEDURE erase_student(n_id students.number_id%type) AS
student_inexistent EXCEPTION;
PRAGMA EXCEPTION_INIT(student_inexistent, -20002);
counter integer;
BEGIN
SELECT COUNT(nmber_id) INTO counter FROM studens where number_id = n_id;
IF counter = 0 THEN
raise student_inexistent;
END IF;
DELETE FROM students WHERE number_id = n_id;
EXCEPTION
WHEN student_inexistent THEN
raise_application_error (-20002, 'Student with number_id' || n_id || ' doesn't exists in database');
END stergere_student;`
答案 0 :(得分:1)
让我们简化您的代码并使其语法正确:
CREATE OR REPLACE PACKAGE package_name
AS
PROCEDURE show_notesforstudent (number_id IN number);
END;
/
CREATE OR REPLACE PACKAGE BODY package_name
AS
PROCEDURE show_notesforstudent (number_id IN number)
AS
BEGIN
erase_student(number_id);
END;
PROCEDURE erase_student(n_id NUMBER) AS BEGIN NULL; END;
END;
/
然而,在我们得到PLS-00313: 'ERASE_STUDENT' not declared in this scope
时,它仍然无法编译。可以通过重新组织包来确定它,以确保在调用私有过程之前声明它;像这样:
CREATE OR REPLACE PACKAGE BODY package_name
AS
PROCEDURE erase_student(n_id NUMBER) AS BEGIN NULL; END; -- Header and body
PROCEDURE show_notesforstudent (number_id IN number)
AS
BEGIN
erase_student(number_id);
END;
END;
/
但是,如果你想保持包中程序的顺序,那么你可以在调用之前使用前向声明来声明私有过程的头,然后声明主体;像这样:
CREATE OR REPLACE PACKAGE BODY package_name
AS
PROCEDURE erase_student(n_id NUMBER); -- Header only
PROCEDURE show_notesforstudent (number_id IN number)
AS
BEGIN
erase_student(number_id);
END;
PROCEDURE erase_student(n_id NUMBER) AS BEGIN NULL; END; -- Header and body
END;
/