2012-09-30 18 views
7

To doprowadza mnie do szału. Chcę zrobić proste porównanie kolumny i zmiennej, ale to po prostu nie działa. Poniższa linia zawsze zlicza wszystkie krotki, podczas gdy ja potrzebuję tylko tych, które są warunkowane klauzulą ​​where.PLSQL Procudure (Oracle) Porównanie zmiennej w miejscu, gdzie klauzula

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

Wygląda to bardzo proste, ale pracuję nad tym od wielu godzin. Kompletny proces sql to

Wielką mylącą rzeczą jest to, że jeśli zastąpię fid z twardym, kodowanym ID (np. 105), to daje to poprawną odpowiedź), ale kiedy używam fid, to po prostu nie działa i zwraca liczba wszystkich klas. Z jakiegoś powodu zawsze class.fid = fid. Kiedy używam>, < lub <>, zwracana jest wartość 0!

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; 

Dzięki

Odpowiedz

7

wierzę, trzeba zmienić nazwę lub prefiks zmienna lokalna fid gdyż niestety pasuje do nazwy kolumny w tabeli jesteś zapytaniem. Silnik SQL po prostu porównuje fid = fid dla każdego wiersza, który zawsze będzie prawdziwy (z wyjątkiem zer, ale to już inna historia). Co więcej, trudniej jest odczytać kod, gdy masz zmienne o tej samej nazwie co kolumna.

W języku PL/SQL istnieje tendencja do prefiksowania zmiennych lokalnych za pomocą l_ (dla lokalnych), więc jasne jest, jaki jest cel. Jednak wystarczy nazwa inna niż nazwa kolumny. Spróbuj:

l_fid faculty.fid%type := 102; 

a potem ...

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

+0

Dziękuję (plus inne odpowiednie zamienniki.)! To był okropny błąd i kosztowało mnie to dużo pracy. Teraz działa! O MÓJ BOŻE! – user1710120

+0

@ user1710120 Cieszę się, że rozwiązałeś problem. Możesz zaznaczyć tę odpowiedź jako poprawną, jeśli chcesz. – Wolf