简体   繁体   中英

How Can I use Case clause within WHERE condition in this procedure?

I'm writing a simple stored procedure for retrieve information about all employees but, I'd add 2 parameters to retrieve information only one employee if is passed for parameter. My intention is create a cursor and add condition in WHERE using parameters but It is not working for now. Do you have any idea? Thanks!

  1. First parameter is for employee id.
  2. Second parameter is for a raise salary.

The procedure is:

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;

Second parameter for raise salary is working but when I add a value for id parameter is currently displaying all employees info.

在此处输入图片说明

You need to re look into the condition "OR fecha_alta IS NOT NULL". All of your records may be having a not null value in your table. Can you first try by commenting out this condition ?

What you want is to select all records if the p_empid is not passed but restrict the result set when it is passed.

The problem is your WHERE clause is not formed tightly enough:

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

Because the condition is specified as a Boolean OR the result sets will include every record where fecha_alta IS NOT NULL , regardless of whether a values is passed in p_empid .

What you need to do is check p_empid in both branches:

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

This version removes the duplication:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM