Oracle
 sql >> Database >  >> RDS >> Oracle

Funzione memorizzata in Oracle che non inserisce valori nella tabella desiderata

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.