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

Lagret funktion i Oracle indsætter ikke værdier i den ønskede tabel

For det første kan du ikke kalde en funktion med DML i det i en udvalgt erklæring. Du skal tildele outputtet til en variabel i en PL/SQL-blok, noget som:

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

Det er dårlig praksis at lave DML i en funktion; dels fordi det forårsager de fejl, du støder på. Du bør bruge en procedure som beskrevet nedenfor. Den anden grund til dette er, at du som altid returnerer null, der er ingen grund til at returnere noget overhovedet!

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

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

end;

Den specifikke årsag til din fejl er denne linje:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');

pBirthdate er allerede en streng; ved at sætte en ' rundt om den sender du strengen 'pBirthdate' til funktionen to_date og Oracle kan ikke konvertere denne streng til en dag, måned eller år, så den mislykkes.

Du skal skrive dette som:
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');

Du behøver heller ikke at angive number(38,0) , du kan bare skrive number i stedet.

Det er muligt at returnere en værdi fra en procedure ved at bruge out søgeord. Hvis vi antager, at du ønsker at returnere empid du kunne skrive sådan noget som dette:

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;

For bare at udføre proceduren kald det sådan her:

begin

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

end;

Hvis du vil returnere empid så kan du kalde det sådan her:

declare

   l_empid number;

begin

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

Bemærk, hvordan jeg har flyttet commit til det højeste niveau er dette for at undgå at begå ting i hver procedure, når du måske har flere ting, du skal gøre.

Hvis du i øvrigt bruger Oracle 11g, er der ingen grund til at tildele værdien A1Seq_Emp.nextval til en variabel. Du kan bare indsætte det direkte i tabellen i values liste. Du vil selvfølgelig ikke kunne returnere den, men du kan returnere A1Seq_Emp.curval , så længe der ikke er andet, der henter værdier fra sekvensen.



  1. Kan ikke oprette forbindelse til MySQL i Cloudbees CommunicationsException:Kommunikationsforbindelsesfejl

  2. Udfyldelse af inputfelt baseret på dropdown menuvalg med Javascript

  3. Hvordan eksporterer jeg en MySQL-database fra PHPMyAdmin og importerer den til SQLite?

  4. Sådan opretter du bruger i Oracle Multitenant 12c uden C## præfiks