Я пытаюсь выполнить функцию внутри пакета. Но я получил эту ошибку «FUNC_RET_NEWSAL» не является процедурой или не определена - PullRequest
0 голосов
/ 29 января 2020

1.Это спецификация моей упаковки

 CREATE OR REPLACE PACKAGE PKG_EMP IS

   V_INC_PRECENT HR.EMPLOYEES.DEPARTMENT_ID%TYPE;

   FUNCTION FUNC_RET_INCRE(P_EMP_ID HR.EMPLOYEES.EMPLOYEE_ID%TYPE)
     RETURN NUMBER;

   FUNCTION FUNC_RET_NEWSAL(P_EMP_ID HR.EMPLOYEES.EMPLOYEE_ID%TYPE)
     RETURN NUMBER;

   PROCEDURE PROC_GET_NAMES(P_EMP   IN HR.EMPLOYEES.EMPLOYEE_ID%TYPE,
                            P_FNAME OUT HR.EMPLOYEES.FIRST_NAME%TYPE,
                            P_LNAME OUT HR.EMPLOYEES.LAST_NAME%TYPE);

   FUNCTION FUNC_RET_FULLNAME(P_FNAME HR.EMPLOYEES.FIRST_NAME%TYPE,
                              P_LNAME HR.EMPLOYEES.LAST_NAME%TYPE)
     RETURN HR.EMPLOYEES.FIRST_NAME%TYPE;

 END PKG_EMP

2.Тело корпуса,

CREATE OR REPLACE PACKAGE BODY PKG_EMP IS
  FUNCTION FUNC_RET_INCRE(P_EMP_ID HR.EMPLOYEES.EMPLOYEE_ID%TYPE) ---calculate increment percentage
   RETURN NUMBER IS
    V_SALARY  HR.EMPLOYEES.SALARY%TYPE;
    V_PCT     NUMBER;
    V_DEPT_ID HR.EMPLOYEES.DEPARTMENT_ID%TYPE;

  BEGIN
    SELECT DEPARTMENT_ID
      INTO V_DEPT_ID
      FROM HR.EMPLOYEES
     WHERE EMPLOYEE_ID = P_EMP_ID;

    V_PCT := V_DEPT_ID / 100;
    RETURN V_PCT;
  END FUNC_RET_INCRE;

  FUNCTION FUNC_RET_NEWSAL(P_EMP_ID HR.EMPLOYEES.EMPLOYEE_ID%TYPE) --- display new salary using previous 
  FUNCTION ---
  RETURN NUMBER IS
    V_SALARY HR.EMPLOYEES.SALARY%TYPE;
    V_PCT    NUMBER;

    V_NEW_SAL HR.EMPLOYEES.SALARY%TYPE;
  BEGIN

    SELECT SALARY
      INTO V_SALARY
      FROM HR.EMPLOYEES
     WHERE EMPLOYEE_ID = P_EMP_ID;
    V_INC_PRECENT := FUNC_RET_INCRE(V_EMP_ID);
    V_NEW_SAL     := V_SALARY + V_INC_PRECENT;
    DBMS_OUTPUT.PUT_LINE(V_NEW_SAL);
    RETURN V_NEW_SAL;
  END FUNC_RET_NEWSAL;

  PROCEDURE PROC_GET_NAMES(P_EMP   IN HR.EMPLOYEES.EMPLOYEE_ID%TYPE,
                           P_FNAME OUT HR.EMPLOYEES.FIRST_NAME%TYPE,
                           P_LNAME OUT HR.EMPLOYEES.LAST_NAME%TYPE) ---- get names separately
   IS
  BEGIN
    SELECT FIRST_NAME, LAST_NAME
      INTO P_FNAME, P_LNAME
      FROM HR.EMPLOYEES
     WHERE EMPLOYEE_ID = P_EMP;
  END PROC_GET_NAMES;

  FUNCTION FUNC_RET_FULLNAME(P_FNAME HR.EMPLOYEES.FIRST_NAME%TYPE,
                             P_LNAME HR.EMPLOYEES.LAST_NAME%TYPE)
    RETURN HR.EMPLOYEES.FIRST_NAME%TYPE IS
    EMP_FULL_NAME HR.EMPLOYEES.FIRST_NAME%TYPE;
  BEGIN
    SELECT CONCAT(CONCAT(P_FNAME, ' '), P_LNAME)
      INTO EMP_FULL_NAME
      FROM HR.EMPLOYEES;
    DBMS_OUTPUT.PUT_LINE(EMP_FULL_NAME);
    RETURN EMP_FULL_NAME;
  END FUNC_RET_FULLNAME;
END PKG_EMP;

3. когда я пытаюсь выполнить это,

EXEC pkg_emp. func_ret_newsal(105);

Я получил ошибку

ORA-06550: строка 1, столбец 7:

PLS-00221: «FUNC_RET_NEWSAL» не является процедурой или не определена

1 Ответ

0 голосов
/ 29 января 2020

Как и в сообщении об ошибке, функция не является процедурой. Разница между функцией и процедурой заключается в том, что функция всегда возвращает значение.

Вы должны присвоить это значение переменной

вызов функции:

declare
  var number; -- if your funtion returns a number
begin
  var := my_func();
end;
/

вызов процедуры:

begin
  my_proc();
end;
/

поэтому в вашем случае, если вы хотите вызвать функцию, вам нужна переменная для присвоения возвращаемого значения

declare
  v number; -- if your funtion returns a number
begin
  v := pkg_emp. func_ret_newsal(105);
end;

или в sqlplus

sql> var v number

sql> begin
  2  select pkg_emp.func_ret_newsal(105) into :v from dual;
  3  end;
  4  /

или

EXEC DBMS_OUTPUT.PUT_LINE(pkg_emp.func_ret_newsal(105));
...