2014-01-13 39 views
2

動態SQL不是我的朋友,基本上我的想法是我可以使用「p_in_table」參數的過程來獲取表中包含的行數。動態SQL LOOP

CREATE OR REPLACE PROCEDURE how_many_rows(p_in_table VARCHAR2) 
IS 
    TYPE cur_cur IS REF CURSOR; 
    v_cur_cur cur_cur; 
    v_rowcount NUMBER(28); 
    v_cur_txt VARCHAR2(299);  
    BEGIN 
    v_cur_txt := 'SELECT * FROM ' || p_in_table; 

    OPEN v_cur_cur FOR v_cur_txt; 

    LOOP 
     v_rowcount := v_cur_cur%ROWCOUNT; 
     EXIT WHEN v_cur_cur%NOTFOUND; 
    END LOOP; 

    CLOSE v_cur_cur; 

    dbms_output.put_line(v_rowcount); 
    END; 

如果有人會告訴我我做錯了什麼,會有用嗎?

+1

使用'select count(*)',你正在做的事是非常低效的。 – Mat

+0

「SELECT COUNT(*)」不是懷疑合理的解決方案,但我也想啃過LOOP問題,只是爲了讓自己更好。 – Novice

+0

這是從表中計算最低效的方法。按照Mat的建議。 – San

回答

3

問題是你沒有通過遊標迭代 - 沒有獲取語句或類似的東西,所以,基本上,你有一個無限循環。爲了避免這種情況,你需要做這樣的事情:

CREATE OR REPLACE PROCEDURE how_many_rows 
    (p_in_table VARCHAR2) IS 
    TYPE cur_cur IS REF CURSOR; 
    v_cur_cur cur_cur; 
    v_rowcount NUMBER(28); 
    v_cur_txt VARCHAR2(299); 
    v_row SOME_TABLE%ROWTYPE; --add row variable 
BEGIN 
    v_cur_txt := 'SELECT * FROM '|| p_in_table; 

OPEN v_cur_cur FOR v_cur_txt; 
    LOOP 
     v_rowcount := v_cur_cur%ROWCOUNT; 
     FETCH v_cur_cur INTO v_row; --fetch a row in it 
     EXIT WHEN v_cur_cur%NOTFOUND; 
    END LOOP; 
CLOSE v_cur_cur; 

DBMS_OUTPUT.PUT_LINE(v_rowcount); 
END; 

但是,正如你所看到的,要做到這一點,你需要知道,你quering什麼表,所以這不是一般的解決方案。也許有解決類似的問題,但我建議,您使用更加簡單和有效的方法,例如使用EXECUTE IMMEDIATE:

CREATE OR REPLACE PROCEDURE HOW_MANY_ROWS(p_in_table VARCHAR2) 
     IS 
v_tmp NUMBER; 
BEGIN 

EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM ' || p_in_table INTO v_tmp; 
DBMS_OUTPUT.PUT_LINE(v_tmp); 

END; 

好吧,我就如何實現這一目標用自己的方式思考,這裏就是我最後的結果 - 只要從你的表格中取出ROWNUM,每個表格都有它,你知道它是類型 - NUMBER。所以這個程序在一般情況下可以工作:

CREATE OR REPLACE PROCEDURE how_many_rows 
    (p_in_table VARCHAR2) IS 
    TYPE cur_cur IS REF CURSOR; 
    v_cur_cur cur_cur; 
    v_rowcount NUMBER(28); 
    v_cur_txt VARCHAR2(299); 
    v_row NUMBER; --add rownum variable 
BEGIN 
    v_cur_txt := 'SELECT ROWNUM FROM '|| p_in_table; --select only rownum from target table 

OPEN v_cur_cur FOR v_cur_txt; 
    LOOP 
     v_rowcount := v_cur_cur%ROWCOUNT; 
     FETCH v_cur_cur INTO v_row; --fetch rownum in it 
     EXIT WHEN v_cur_cur%NOTFOUND; 
    END LOOP; 
CLOSE v_cur_cur; 

DBMS_OUTPUT.PUT_LINE(v_rowcount); 
END;