sql >> Base de Datos >  >> RDS >> Oracle

Función almacenada en Oracle que no inserta valores en la tabla deseada

En primer lugar, no puede llamar a una función con DML en él en una declaración selecta. Tienes que asignar la salida a una variable en un bloque PL/SQL, algo como:

declare
  l_output number;
begin
  l_output := my_function(variable1, variable2);
end;

Es una mala práctica hacer DML en una función; en parte porque causa los errores que estás encontrando. Debe utilizar un procedimiento como se detalla a continuación. La otra razón de esto es que, como siempre, devuelve nulo, ¡no hay necesidad de devolver nada en absoluto!

create or replace procedure my_procedure ( <variables> ) is
begin

   insert into employees( <columns> )
   values ( <values > );

end;

El motivo específico de su error es esta línea:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');

pBirthdate ya es una cadena; poniendo un ' a su alrededor está pasando la cadena 'pBirthdate' a la función to_date y Oracle no puede convertir esta cadena en un día, mes o año, por lo que está fallando.

Debes escribir esto como:
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');

Tampoco necesita especificar number(38,0) , puedes escribir number en su lugar.

Es posible devolver un valor de un procedimiento usando out palabra clave. Si asumimos que desea devolver empid podrías escribir algo como esto:

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;

Para simplemente ejecutar el procedimiento, llámelo así:

begin

    A1SF_ADDEMP( EmpName, TaxFileNo, Gender
               , Salary, Birthdate);
    commit;

end;

Si desea devolver el empid entonces puedes llamarlo así:

declare

   l_empid number;

begin

   l_empid := A1SF_ADDEMP( EmpName, TaxFileNo, Gender
                         , Salary, Birthdate);
   commit;
end;

Observe cómo he movido el commit al más alto nivel, esto es para evitar cometer cosas en cada procedimiento cuando es posible que tenga más cosas que hacer.

Por cierto, si está utilizando Oracle 11g, no es necesario asignar el valor A1Seq_Emp.nextval a una variable. Simplemente puede insertarlo directamente en la tabla en los values lista. Por supuesto, no podrá devolverlo, pero podría devolver A1Seq_Emp.curval , siempre que no haya nada más que obtenga valores de la secuencia.