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.