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
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With