Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Função Armazenada no Oracle não Inserindo Valores na tabela desejada


Em primeiro lugar, você não pode chamar uma função com DML nele em uma instrução select. Você tem que atribuir a saída a uma variável em um bloco PL/SQL, algo como:
declare
  l_output number;
begin
  l_output := my_function(variable1, variable2);
end;

É uma má prática fazer DML em uma função; em parte porque causa os erros que você está encontrando. Você deve usar um procedimento conforme detalhado abaixo. A outra razão para isso é que você está sempre retornando null, não há necessidade de retornar nada!
create or replace procedure my_procedure ( <variables> ) is
begin

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

end;

O motivo específico do seu erro é esta linha:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');

pBirthdate já é uma string; colocando um ' em torno dele você está passando a string 'pBirthdate' para a função to_date e o Oracle não pode converter essa string em um dia, mês ou ano, então está falhando.

Você deve escrever isso como:
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');

Você também não precisa especificar number(38,0) , você pode simplesmente escrever number em vez de.

É possível retornar um valor de um procedimento usando o out palavra-chave. Se presumirmos que você deseja retornar empid você poderia escrever é algo assim:
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 apenas executar o procedimento, chame-o assim:
begin

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

end;

Se você deseja retornar o empid então você pode chamar assim:
declare

   l_empid number;

begin

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

Observe como movi o commit ao nível mais alto, isso é para evitar cometer coisas em todos os procedimentos quando você pode ter mais coisas que precisa fazer.

Aliás, se você estiver usando o Oracle 11g, não há necessidade de atribuir o valor A1Seq_Emp.nextval a uma variável. Você pode simplesmente inseri-lo diretamente na tabela nos values Lista. Você, é claro, não poderá devolvê-lo, mas pode retornar A1Seq_Emp.curval , desde que não haja mais nada obtendo valores da sequência.