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.