Во-первых, вы не можете вызвать функцию с DML в операторе выбора. Вы должны назначить вывод переменной в блоке PL / SQL, что-то вроде:
declare
l_output number;
begin
l_output := my_function(variable1, variable2);
end;
Это плохая практика - использовать DML в функции; частично потому что это вызывает ошибки, с которыми вы сталкиваетесь. Вы должны использовать процедуру, описанную ниже. Другая причина этого в том, что вы как всегда возвращаете null, и вам вообще не нужно ничего возвращать!
create or replace procedure my_procedure ( <variables> ) is
begin
insert into employees( <columns> )
values ( <values > );
end;
Конкретная причина вашей ошибки - эта строка:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');
pBirthdate
уже является строкой; поместив вокруг него '
, вы передаете строку 'pBirthdate'
функции to_date
, и Oracle не может преобразовать эту строку в день, месяц или год, поэтому она не работает.
Вы должны написать это как:
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');
Вам также не нужно указывать number(38,0)
, вы можете просто написать number
.
Можно вернуть значение из процедуры, используя ключевое слово out
. Если мы предполагаем, что вы хотите вернуть empid
, вы можете написать что-то вроде этого:
create or replace procedure A1SF_ADDEMP (
pEmpName in varchar2
, pTaxFileNo in varchar2
, pGender in varchar2
, pSalary in number
, pBirthdate in varchar2
, pEmpid out number
) return varchar2 is
begin
pempid := A1Seq_Emp.nextval;
Insert Into Employee(EmpId, EmpName, TaxFileNo, Gender, Salary, Birthdate)
Values ( pEmpId, pEmpName, pTaxFileNo, pGender
, pSalary, to_date(pBirthdate,'dd/mm/yyyy');
end;
Чтобы просто выполнить процедуру, вызовите ее так:
begin
A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Если вы хотите вернуть empid
, вы можете назвать его так:
declare
l_empid number;
begin
l_empid := A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Обратите внимание на то, как я переместил commit
на самый высокий уровень, чтобы избежать фиксации вещей в каждой процедуре, когда у вас может быть больше вещей, которые вам нужно сделать.
Кстати, если вы используете Oracle 11g, тогда нет необходимости присваивать значение A1Seq_Emp.nextval
переменной. Вы можете просто вставить его прямо в таблицу в списке values
. Вы, конечно, не сможете его вернуть, но вы можете вернуть A1Seq_Emp.curval
, если больше ничего не получит значения из последовательности.