sql >> Databasteknik >  >> RDS >> Oracle

Lagrad funktion i Oracle infogar inte värden i önskad tabell

För det första kan du inte anropa en funktion med DML i det i ett utvalt uttalande. Du måste tilldela utdata till en variabel i ett PL/SQL-block, ungefär som:

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

Det är dålig praxis att göra DML i en funktion; delvis för att det orsakar de fel du stöter på. Du bör använda en procedur som beskrivs nedan. Den andra anledningen till detta är att du som alltid returnerar null, det finns inget behov av att returnera något alls!

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

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

end;

Den specifika orsaken till ditt fel är denna rad:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');

pBirthdate är redan en sträng; genom att sätta en ' runt den skickar du strängen 'pBirthdate' till funktionen to_date och Oracle kan inte konvertera den här strängen till en dag, månad eller år så det misslyckas.

Du bör skriva detta som:
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');

Du behöver inte heller ange number(38,0) , du kan bara skriva number istället.

Det är möjligt att returnera ett värde från en procedur med out nyckelord. Om vi ​​antar att du vill returnera empid du kan skriva är ungefär så här:

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;

För att bara utföra proceduren, kalla den så här:

begin

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

end;

Om du vill returnera empid då kan du kalla det så här:

declare

   l_empid number;

begin

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

Lägg märke till hur jag har flyttat commit till högsta nivå är detta för att undvika att begå saker i varje procedur när du kanske har fler saker du behöver göra.

För övrigt, om du använder Oracle 11g behöver du inte tilldela värdet A1Seq_Emp.nextval till en variabel. Du kan bara infoga den direkt i tabellen i values lista. Du kommer naturligtvis inte att kunna returnera den, men du kan returnera A1Seq_Emp.curval , så länge det inte finns något annat som hämtar värden från sekvensen.



  1. Återanvänds numeriska primärnycklar för raderade poster i en databas för framtida nya poster?

  2. Hur kan vi förhindra SQL-injektion från MySQL?

  3. ORACLE - regexp_substr för att returnera nollvärden

  4. Insamlingsmetod:COUNT-funktion i Oracle Database