Найти бонус заданного empid с помощью функции в PL / SQL - PullRequest
0 голосов
/ 07 марта 2020
  • Но здесь я хочу бонус в 100 и я получаю 24000. Я пробовал без курсора, но затем я ничего не получаю в бонусном идентификаторе только сотрудника, которого я могу видеть. Как программа компилируется без ошибок. Есть ли ненужные вещи, которые я должен удалить, это будет полезно

    CREATE OR REPLACE FUNCTION bonuss  
           (emp_id   IN   NUMBER)
            RETURN NUMBER 
          AS 
            SAL employees.salary%TYPE;
            commis employees.commission_pct%TYPE;
            Annualsalary NUMBER;
            bonus NUMBER;
            cursor x IS
            SELECT salary, commission_pct FROM employees for update of salary;
        BEGIN
        open x;
         loop 
          fetch x into sal, commis;
          exit when x%notfound;
            if commis is null then
                if Annualsalary <= 10000 then 
                bonus := 500;
                elsif Annualsalary > 10000 then 
                bonus := 100;  
                else bonus := 0;
                end if;
            else
                if Annualsalary <= 10000 then 
                bonus := 500;
                elsif Annualsalary > 10000 then 
                bonus := 100;  
                else bonus := 0;
                end if;
            end if;
              Annualsalary := sal * ( 1 + NVL (commis, 0) ); 
            RETURN Annualsalary;
            DBMS_OUTPUT.PUT_LINE('total income of each emp: ' || sal ||',The bonus is ' || bonus);
        end loop;
        close x;
        END bonuss;
        /
    
        Declare 
           emp_bonus       number;
           employee_no     number;
    
         BEGIN
             employee_no :=  205;
             emp_bonus   :=  bonuss (employee_no);
             DBMS_OUTPUT.PUT_LINE ('Employee with ID ' || employee_no ||
             ' will get bonus ' ||emp_bonus) ;
        END;
        /  
    Output:
    
    Function BONUSS dropped.
    
    
    Function BONUSS compiled
    
    Employee with ID 205 will get bonus 24000
    
    
    PL/SQL procedure successfully completed.
    

1 Ответ

1 голос
/ 07 марта 2020

Я вижу много потенциальных ошибок, некоторые из которых связаны с вашей проблемой, а некоторые нет.

Во-первых, настоящая причина вашей ошибки заключается в том, что ваш курсор не фильтрует идентификатор сотрудника. Таким образом, вы накапливаете для всех сотрудников.

Далее, вам не следует выполнять SELECT ... FOR UPDATE в функции. Цель функции - вернуть значение. Период. Полная остановка. Не следует ожидать обновления.

Далее вы продолжаете сравнивать Годовой заработок с некоторым фиксированным значением, но я не вижу нигде в коде, где вы присваиваете значение Годовому окладу.

Помимо этих технических ошибок Если бы я писал это, я бы сделал несколько «стилевых» изменений.

Во-первых, нет смысла писать код в смешанном регистре в oracle. Хотя с технической точки зрения в этом нет ничего плохого, это все равно что говорить по-английски sh (oracle) с сильным французским (Microsoft) акцентом. В мире oracle вместо смешанного регистра («CamelCase») мы склонны использовать все строчные буквы с подчеркиванием. Например, вместо «EmployeeName» мы будем использовать «employee_name».

Далее, в вашем объявлении переменной, я настоятельно рекомендую стандартизировать некоторые префиксы для указания типа переменной: «p_» для parms, «v_» для переменных, «c_» для констант. Таким образом, когда вы увидите там ссылки в длинном коде, станет ясно, что это за элемент. Чтобы изменить ваш код в соответствии с этим стандартом:

create or replace function bonuss  
       (p_emp_id   in number)
        return number 
      as 
        v_sal employees.salary%type;
        v_commis employees.commission_pct%type;
        v_annual_salary number;
        v_bonus number;

Далее, если бы я использовал явный курсор (я бы не стал), я бы дал ему осмысленное имя, которое также указывает (для дальнейшего использования) что это курсор:

cursor csr_emp IS

Но я бы вообще не использовал явный курсор. Я бы использовал 'курсор для l oop':

begin
  for x in (select salary, 
                   commission_pct 
            from employees
            where emp_id  = p_emid  '<<---- important to your case!)
)
    if x.commission_pct is null 
    <rest of code>
  loop;
end;

Но так как кажется, что вы хотите, чтобы функция возвращала бонус для одного сотрудника (иначе, почему emp_id является входным параметром ?) вам даже не нужен курсор вообще.

...