7

これは私を夢中にさせています。列と変数の単純な比較をしたいのですが、うまくいきません。次の行は常にすべてのタプルをカウントしますが、where 句によって条件付けられたタプルのみが必要です。

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

とてもシンプルに見えますが、私はこれに何時間も取り組んできました。完全な sql プロシージャは次のとおりです。

非常に紛らわしいのは、fid をハードコードされた ID (105 など) に置き換えると正しい答えが得られることですが、fid を使用すると機能しなくなり、すべてのクラスのカウントが返されます。何らかの理由で、常に class.fid = fid になります。>、<、または <> を使用すると、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;

ありがとう

4

1 に答える 1

7

fid残念ながら、クエリしているテーブルの列名と一致するため、ローカル変数の名前を変更するか、プレフィックスを付ける必要があると思います。fid = fidSQL エンジンは単に各行を比較しているだけで、これは常に true になります (null を除くが、それは別の話です)。さらに、列と同じ名前の変数があると、コードが読みにくくなります。

PL/SQL では、ローカル変数の前に (ローカルの) を付ける慣習がある傾向があるl_ため、目的が明確になります。ただし、列名以外の名前で十分です。試す:

l_fid faculty.fid%type := 102;

その後...

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

(さらに、他の適切な代替品。)

于 2012-09-30T18:12:26.980 に答える