sql >> Database >  >> RDS >> Oracle

Opgeslagen functie in Oracle voegt geen waarden in de gewenste tabel in

Ten eerste kun je geen functie aanroepen met DML daarin in een select statement. Je moet de output toewijzen aan een variabele in een PL/SQL-blok, zoiets als:

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

Het is een slechte gewoonte om DML in een functie te doen; deels omdat het de fouten veroorzaakt die je tegenkomt. U moet een procedure gebruiken zoals hieronder beschreven. De andere reden hiervoor is dat je zoals altijd null retourneert, het is helemaal niet nodig om iets te retourneren!

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

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

end;

De specifieke reden voor je fout is deze regel:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');

pBirthdate is al een string; door een ' . te plaatsen daaromheen geef je de string 'pBirthdate' . door naar de functie to_date en Oracle kan deze string niet omzetten in een dag, maand of jaar, dus het mislukt.

Je moet dit schrijven als:
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');

U hoeft ook geen number(38,0) op te geven , je kunt gewoon number schrijven in plaats daarvan.

Het is mogelijk om een ​​waarde uit een procedure terug te geven met behulp van de out trefwoord. Als we aannemen dat je empid wilt retourneren je zou kunnen schrijven is zoiets als dit:

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;

Om de procedure gewoon uit te voeren, roept u het als volgt aan:

begin

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

end;

Als u de empid . wilt retourneren dan kun je het zo noemen:

declare

   l_empid number;

begin

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

Merk op hoe ik de commit . heb verplaatst op het hoogste niveau, dit is om te voorkomen dat u dingen vastlegt in elke procedure wanneer u mogelijk meer dingen moet doen.

Overigens, als u Oracle 11g gebruikt, hoeft u de waarde A1Seq_Emp.nextval niet toe te wijzen naar een variabele. Je kunt het gewoon rechtstreeks in de tabel invoegen in de values lijst. U kunt het natuurlijk niet retourneren, maar u kunt A1Seq_Emp.curval , zolang er niets anders waarden uit de reeks haalt.



  1. Gegevens van de ene tabel in de andere invoegen in MySQL

  2. Overzicht creëren over verschillende databases

  3. Hoe threadveilig is EnableWriteAheadLogging in de context van echt gebruik en SQLite-documentatie?

  4. Ontdek de aanroepende opgeslagen procedure in SQL Server