2012-09-30 27 views
7

Esto me está volviendo loco. Quiero hacer una comparación simple de una columna y una variable, pero simplemente no funciona. La siguiente línea siempre cuenta todas las tuplas, mientras que solo las necesito condicionadas por la cláusula where.PLSQL Procudure (Oracle) Comparando una variable en where clause

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

Parece tan simple pero he estado trabajando en esto durante horas. El proceso sql completo es

Lo más confuso es que si reemplazo fid con una identificación codificada (como 105) da una respuesta correcta), pero cuando uso fid ya no funciona y regresa recuento de todas las clases. Por alguna razón, siempre class.fid = fid. Cuando uso>, < o <>, se devuelve 0 count!

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; 

Gracias

Respuesta

7

creo que necesita cambiar el nombre o prefijo local de la variable de fid ya que lamentablemente coincide con el nombre de columna en la tabla que está consultando. El motor de SQL simplemente está comparando fid = fid para cada fila, lo que siempre será cierto (excepto nulos, pero esa es otra historia). Además, es más difícil leer su código cuando tiene variables con el mismo nombre que una columna.

En PL/SQL suele haber una convención para prefijar las variables locales con un l_ (para local) por lo que está claro cuál es el propósito. Sin embargo, cualquier nombre que no sea un nombre de columna será suficiente. Proveedores:

l_fid faculty.fid%type := 102; 

Y entonces ...

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

+0

Gracias (Plus otros reemplazos adecuados.)! Ese fue un error horrible y me costó mucho trabajo. ¡Ahora funciona! ¡DIOS MIO! – user1710120

+0

@ user1710120 Me alegra que hayas resuelto el problema. Le invitamos a marcar esta respuesta como correcta si lo desea. – Wolf