Oracle
 sql >> база данни >  >> RDS >> Oracle

Съхранената функция в Oracle не вмъква стойности в желаната таблица

Първо, не можете да извикате функция с DML в него в израз за избор. Трябва да присвоите изхода на променлива в PL/SQL блок, нещо като:

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

Лоша практика е да се прави DML във функция; отчасти защото причинява грешките, на които се натъквате. Трябва да използвате процедура, описана по-долу. Другата причина за това е, че както винаги връщате null, няма нужда да връщате нищо!

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

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

end;

Конкретната причина за вашата грешка е този ред:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');

pBirthdate вече е низ; като поставите ' около него предавате низа 'pBirthdate' към функцията to_date и Oracle не може да преобразува този низ в ден, месец или година, така че се проваля.

Трябва да напишете това като:
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');

Също така не е необходимо да указвате number(38,0) , можете просто да напишете number вместо това.

Възможно е да се върне стойност от процедура с помощта на out ключова дума. Ако приемем, че искате да върнете empid можете да напишете нещо подобно:

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;

За да изпълните процедурата, извикайте я така:

begin

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

end;

Ако искате да върнете empid тогава можете да го наречете така:

declare

   l_empid number;

begin

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

Забележете как преместих commit до най-високо ниво, това е, за да се избегне ангажирането на неща във всяка процедура, когато може да имате повече неща, които трябва да направите.

Между другото, ако използвате Oracle 11g, тогава няма нужда да присвоявате стойността A1Seq_Emp.nextval към променлива. Можете просто да го вмъкнете директно в таблицата в values списък. Вие, разбира се, няма да можете да го върнете, но можете да върнете A1Seq_Emp.curval , стига нищо друго да не получава стойности от последователността.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Каква е разликата между ORA-12571:грешка при писане на TNS пакети и ORA-03135:връзката е изгубена?

  2. Oracle 10g:Могат ли дължините на CLOB данни да бъдат по-малки от 4000?

  3. ora:00936 Грешка при липсващ израз

  4. Позволено ли е използването на SELECT в конвейерна PL/SQL таблична функция?

  5. Изпълнете функция на Oracle, която връща референтен курсор в C#