Trước hết, bạn không thể gọi một hàm với DML trong đó trong một câu lệnh chọn. Bạn phải gán đầu ra cho một biến trong khối PL / SQL, giống như:
declare
l_output number;
begin
l_output := my_function(variable1, variable2);
end;
Thực hành không tốt khi thực hiện DML trong một hàm; một phần vì nó gây ra các lỗi bạn đang gặp phải. Bạn nên sử dụng một quy trình như chi tiết bên dưới. Lý do khác cho điều này là bạn luôn trả về null, không cần trả lại bất cứ thứ gì!
create or replace procedure my_procedure ( <variables> ) is
begin
insert into employees( <columns> )
values ( <values > );
end;
Lý do cụ thể cho lỗi của bạn là dòng này:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');
pBirthdate
đã là một chuỗi; bằng cách đặt một '
xung quanh nó, bạn đang chuyển chuỗi 'pBirthdate'
vào hàm to_date
và Oracle không thể chuyển đổi chuỗi này thành ngày, tháng hoặc năm nên nó không thành công.
Bạn nên viết cái này là:
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');
Bạn cũng không cần chỉ định number(38,0)
, bạn chỉ có thể viết number
thay vào đó.
Có thể trả về giá trị từ một thủ tục bằng cách sử dụng out
từ khóa. Nếu chúng tôi giả định rằng bạn muốn trả về empid
bạn có thể viết như thế này:
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;
Để chỉ thực hiện thủ tục, hãy gọi nó như thế này:
begin
A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Nếu bạn muốn trả lại empid
thì bạn có thể gọi nó như thế này:
declare
l_empid number;
begin
l_empid := A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Lưu ý cách tôi đã di chuyển commit
ở mức cao nhất, điều này là để tránh phạm phải nhiều thứ trong mọi quy trình khi bạn có thể có nhiều việc cần làm.
Ngẫu nhiên, nếu bạn đang sử dụng Oracle 11g thì không cần gán giá trị A1Seq_Emp.nextval
vào một biến. Bạn chỉ có thể chèn trực tiếp nó vào bảng trong các giá trị values
danh sách. Tất nhiên, bạn sẽ không thể trả lại, nhưng bạn có thể trả lại A1Seq_Emp.curval
, miễn là không có gì khác nhận giá trị từ chuỗi.