如何在此过程中的WHERE条件中使用Case子句?

时间:2017-06-03 16:48:15

标签: sql oracle stored-procedures plsql case

我正在编写一个简单的存储过程来检索有关所有员工的信息,但是,如果为参数传递,我会添加2个参数来检索仅一个员工的信息。我的目的是创建一个游标并使用参数在WHERE中添加条件,但它现在不起作用。你有什么主意吗?谢谢!

  1. 第一个参数是员工ID。
  2. 第二个参数是加薪。
  3. 程序是:

    CREATE OR REPLACE PROCEDURE test6(
            p_empid        empleados.legajo%TYPE := NULL,
            p_raise_salary empleados.sueldo_basico%TYPE := NULL)
    IS
        CURSOR c_emps
        IS
            SELECT legajo, apellido, nombre, fecha_alta, sueldo_basico,
                   (CASE
                        WHEN p_raise_salary IS NOT NULL THEN
                            sueldo_basico * p_raise_salary
                        ELSE
                            sueldo_Basico
                    END) aumento_sueldo_basico
            FROM    empleados
            WHERE  (legajo = p_empid AND fecha_alta IS NOT NULL)
            OR     fecha_alta IS NOT NULL;
    BEGIN
        FOR i IN c_emps
        LOOP
            DBMS_OUTPUT.PUT_LINE(
                'NOMBRE: ' || i.apellido || ' ' || i.nombre || ' ' || i.legajo);
            DBMS_OUTPUT.PUT_LINE(
                'Antiguo Sueldo: ' || i.sueldo_basico);
            DBMS_OUTPUT.PUT_LINE(
                'Nuevo Sueldo: ' || i.aumento_sueldo_basico);
    
            EXIT WHEN c_emps%NOTFOUND;
        END LOOP;
    END test6;
    

    提高工资的第二个参数正在运作,但当我为id参数添加值时,当前正在显示所有员工信息。

    enter image description here

2 个答案:

答案 0 :(得分:0)

你需要重新审视条件"或者fecha_alta IS NOT NULL"。您的所有记录可能在表中具有非空值。你能先试着评论这个条件吗?

答案 1 :(得分:0)

如果p_empid未通过,则选择所有记录,但在传递结果集时限制结果集。

问题是你的WHERE子句形成得不够紧密:

    WHERE  (legajo = p_empid AND fecha_alta IS NOT NULL)
    OR     fecha_alta IS NOT NULL;

由于条件被指定为布尔值,因此结果集将包括每个记录fecha_alta IS NOT NULL,而不管是否在p_empid中传递值。

您需要做的是检查两个分支中的p_empid

    WHERE  (legajo = p_empid AND fecha_alta IS NOT NULL)
    OR     (p_empid IS NULL AND fecha_alta IS NOT NULL);

此版本删除了重复:

CREATE OR REPLACE PROCEDURE test6(
        p_empid        empleados.legajo%TYPE := NULL,
        p_raise_salary empleados.sueldo_basico%TYPE := NULL)
IS
    CURSOR c_emps
    IS
        SELECT legajo, apellido, nombre, fecha_alta, sueldo_basico,
               (CASE
                    WHEN p_raise_salary IS NOT NULL THEN
                        sueldo_basico * p_raise_salary
                    ELSE
                        sueldo_Basico
                END) aumento_sueldo_basico
        FROM    empleados
        WHERE  (p_empid IS NULL or legajo = p_empid)
        AND    fecha_alta IS NOT NULL;
BEGIN
    FOR i IN c_emps
    LOOP
        DBMS_OUTPUT.PUT_LINE(
            'NOMBRE: ' || i.apellido || ' ' || i.nombre || ' ' || i.legajo);
        DBMS_OUTPUT.PUT_LINE(
            'Antiguo Sueldo: ' || i.sueldo_basico);
        DBMS_OUTPUT.PUT_LINE(
            'Nuevo Sueldo: ' || i.aumento_sueldo_basico);

        EXIT WHEN c_emps%NOTFOUND;
    END LOOP;
END test6;