Po pierwsze nie możesz wywołać funkcji z DML w nim w instrukcji select. Musisz przypisać wyjście do zmiennej w bloku PL/SQL, coś takiego:
declare
l_output number;
begin
l_output := my_function(variable1, variable2);
end;
Złą praktyką jest wykonywanie DML w funkcji; częściowo dlatego, że powoduje błędy, na które się natykasz. Powinieneś zastosować procedurę opisaną poniżej. Innym powodem jest to, że jak zawsze zwracasz wartość null, nie ma potrzeby zwracania czegokolwiek!
create or replace procedure my_procedure ( <variables> ) is
begin
insert into employees( <columns> )
values ( <values > );
end;
Konkretną przyczyną błędu jest ten wiersz:tBirthdate := to_date('pBirthdate','dd/mm/yyyy');
pBirthdate
jest już ciągiem; umieszczając '
wokół niego przekazujesz ciąg 'pBirthdate'
do funkcji to_date
a Oracle nie może przekonwertować tego ciągu na dzień, miesiąc lub rok, więc kończy się niepowodzeniem.
Powinieneś napisać to jako:tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');
Nie musisz również określać number(38,0)
, możesz po prostu napisać number
zamiast tego.
Możliwe jest zwrócenie wartości z procedury za pomocą out
słowo kluczowe. Jeśli założymy, że chcesz zwrócić empid
możesz napisać coś takiego:
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;
Aby wykonać tę procedurę, wywołaj ją tak:
begin
A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Jeśli chcesz zwrócić empid
możesz to nazwać tak:
declare
l_empid number;
begin
l_empid := A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Zwróć uwagę, jak przeniosłem commit
do najwyższego poziomu, aby uniknąć popełniania błędów w każdej procedurze, gdy możesz mieć więcej rzeczy do zrobienia.
Nawiasem mówiąc, jeśli używasz Oracle 11g, nie ma potrzeby przypisywania wartości A1Seq_Emp.nextval
do zmiennej. Możesz po prostu wstawić go bezpośrednio do tabeli w values
lista. Oczywiście nie będziesz mógł go zwrócić, ale możesz zwrócić A1Seq_Emp.curval
, o ile nic więcej nie pobiera wartości z sekwencji.