Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PLSQL Procudure (Oracle) Comparing a variable in where clause

This is driving me crazy. I want to do simple comparison of a column and a variable but it just doesn't work. The following line always counts all of the tuples while I only need those as conditioned by the where clause.

 SELECT count(*) INTO cnt from class where class.fid = fid;

It looks sooooo simple but I've been working on this for hours. The complete sql proc is

The big confusing thing is that if I replace fid with some hard coded ID (like 105) it gives a correct answer), but when I use fid it just doesn't work any more and returns count of all classes. For some reason, always class.fid = fid. When I use >, < or <>, 0 count is returned!

create or replace PROCEDURE pro_report2
AS
CURSOR c_dept IS select deptid, dname from department;
TYPE cur_typ IS REF CURSOR;
c1 cur_typ;
query_str1 VARCHAR2(200);
fid faculty.fid%type := 102;
fname faculty.fname%type;
cnt NUMBER;

BEGIN
    FOR dept_row in c_dept LOOP
        DBMS_OUTPUT.PUT_LINE('Dept.Name: ' || dept_row.dname);
        DBMS_OUTPUT.PUT_LINE('Faculty Name' || chr(9)|| chr(9) || '0 Class' || chr(9) || chr(9) || '1 Class' || chr(9) || chr(9) || '2 Classes' || chr(9) || '>2 Classes');
        DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------');
        --find all faculty in this department
        query_str1 := 'select fid, fname from faculty where faculty.deptid = ' || to_char(dept_row.deptid);
        open c1 for query_str1;
        LOOP
            FETCH c1 into fid, fname;
            exit when c1%notfound;
            DBMS_OUTPUT.PUT_LINE(fname);
            SELECT count(*) INTO cnt from class where class.fid = fid;
            DBMS_OUTPUT.PUT_LINE(to_char(cnt) || '    ' || to_char(fid));
        END LOOP;
        -- Spaces between departments
        DBMS_OUTPUT.PUT_LINE(chr(10));
        DBMS_OUTPUT.PUT_LINE(chr(10));
    END LOOP;
END;

Thanks

like image 556
user1710120 Avatar asked Sep 30 '12 17:09

user1710120


1 Answers

I believe you need to rename or prefix your local variable fid as it unfortunately matches the column name in the table you are querying. The SQL engine is simply comparing fid = fid for each row, which will always be true (excepting nulls, but that's another story). Plus, it's harder to read your code when you have variables named the same as a column.

In PL/SQL there tends to be a convention to prefix local variables with a l_ (for local) so it's clear what the purpose is. However, any name other than a column name will suffice. Try:

l_fid faculty.fid%type := 102;

And then...

SELECT count(*) INTO cnt from class where class.fid = l_fid;

(Plus other appropriate replacements.)

like image 176
Wolf Avatar answered Oct 22 '22 03:10

Wolf