Innanzitutto non puoi chiamare una funzione con DML in esso in una dichiarazione select. Devi assegnare l'output a una variabile in un blocco PL/SQL, qualcosa come:
declare
l_output number;
begin
l_output := my_function(variable1, variable2);
end;
È una cattiva pratica eseguire DML in una funzione; in parte perché provoca gli errori che stai riscontrando. È necessario utilizzare una procedura come descritto di seguito. L'altro motivo è che come sempre restituisci null non è necessario restituire nulla!
create or replace procedure my_procedure ( <variables> ) is
begin
insert into employees( <columns> )
values ( <values > );
end;
Il motivo specifico del tuo errore è questa riga:tBirthdate := to_date('pBirthdate','dd/mm/yyyy');
pBirthdate
è già una stringa; inserendo un '
attorno ad esso stai passando la stringa 'pBirthdate'
alla funzione to_date
e Oracle non può convertire questa stringa in un giorno, mese o anno, quindi non riesce.
Dovresti scriverlo come:tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');
Inoltre, non è necessario specificare number(38,0)
, puoi semplicemente scrivere number
invece.
È possibile restituire un valore da una procedura utilizzando il out
parola chiave. Se assumiamo che tu voglia restituire empid
potresti scrivere è qualcosa del genere:
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;
Per eseguire semplicemente la procedura, chiamala in questo modo:
begin
A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Se vuoi restituire il empid
allora puoi chiamarlo così:
declare
l_empid number;
begin
l_empid := A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Nota come ho spostato il commit
al livello più alto, questo serve per evitare di impegnare cose in ogni procedura quando potresti avere più cose che devi fare.
Per inciso, se stai utilizzando Oracle 11g, non è necessario assegnare il valore A1Seq_Emp.nextval
ad una variabile. Puoi semplicemente inserirlo direttamente nella tabella nei values
elenco. Ovviamente non potrai restituirlo, ma potresti restituire A1Seq_Emp.curval
, purché non ci sia nient'altro che ottenga valori dalla sequenza.