Tout d'abord, vous ne pouvez pas appeler une fonction avec DML dedans dans une instruction select. Vous devez affecter la sortie à une variable dans un bloc PL/SQL, quelque chose comme :
declare
l_output number;
begin
l_output := my_function(variable1, variable2);
end;
C'est une mauvaise pratique de faire du DML dans une fonction; en partie parce que cela provoque les erreurs que vous rencontrez. Vous devez utiliser une procédure comme détaillé ci-dessous. L'autre raison à cela est que vous retournez comme toujours null, il n'est pas nécessaire de retourner quoi que ce soit !
create or replace procedure my_procedure ( <variables> ) is
begin
insert into employees( <columns> )
values ( <values > );
end;
La raison spécifique de votre erreur est cette ligne :tBirthdate := to_date('pBirthdate','dd/mm/yyyy');
pBirthdate
est déjà une chaîne ; en mettant un '
autour de lui, vous passez la chaîne 'pBirthdate'
à la fonction to_date
et Oracle ne peut pas convertir cette chaîne en jour, mois ou année donc ça échoue.
Vous devez l'écrire sous la forme :tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');
Vous n'avez pas non plus besoin de spécifier number(38,0)
, vous pouvez simplement écrire number
à la place.
Il est possible de retourner une valeur d'une procédure en utilisant le out
mot-clé. Si nous supposons que vous souhaitez renvoyer empid
vous pourriez écrire quelque chose comme ceci :
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;
Pour simplement exécuter la procédure, appelez-la comme ceci :
begin
A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Si vous voulez retourner le empid
alors vous pouvez l'appeler comme ceci :
declare
l_empid number;
begin
l_empid := A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Remarquez comment j'ai déplacé le commit
au plus haut niveau, c'est pour éviter de commettre des choses dans chaque procédure alors que vous pourriez avoir plus de choses à faire.
Incidemment, si vous utilisez Oracle 11g, il n'est pas nécessaire d'attribuer la valeur A1Seq_Emp.nextval
à une variable. Vous pouvez simplement l'insérer directement dans le tableau dans les values
liste. Vous ne pourrez bien sûr pas le retourner, mais vous pouvez retourner A1Seq_Emp.curval
, tant que rien d'autre ne récupère les valeurs de la séquence.