CREATE OR REPLACE PROCEDURE test_table IS
l_table_name VARCHAR2(50);
query_stmt VARCHAR2(200);
l_rec t_djjcxx%ROWTYPE; -- 表類型變量,接收整行
l_jh VARCHAR2(20) := '7874';
BEGIN
-- 1. 動態獲取表名
SELECT name INTO l_table_name FROM testa;
-- 2. 構建動態查詢 (使用綁定變量 :l_jh)
query_stmt := 'SELECT * FROM ' || l_table_name || ' WHERE jh = :l_jh';
-- 3. EXECUTE IMMEDIATE ... INTO 變量 USING 綁定值
EXECUTE IMMEDIATE query_stmt INTO l_rec USING l_jh;
-- 4. 使用結果
DBMS_OUTPUT.PUT_LINE('ZYQ=' || l_rec.zyq);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No data for JH=' || l_jh);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;
/
query_stmt 僅含 SELECT ... FROM ... WHERE ...,INTO 放在 EXECUTE IMMEDIATE 之後。:l_jh,USING 子句按順序傳遞值。%ROWTYPE 或 RECORD 類型,避免列數/類型不匹配。BULK COLLECT INTO 集合或 OPEN ... FOR 游標。| 錯誤寫法 | 問題 | 正確寫法 |
|---|---|---|
EXECUTE IMMEDIATE 'SELECT col INTO v FROM t' USING ... | 動態串包含 INTO | EXECUTE IMMEDIATE 'SELECT col FROM t' INTO v USING ... |
EXECUTE IMMEDIATE 'SELECT * FROM t WHERE id=' || v_id | 拼接值導致注入/解析開銷 | EXECUTE IMMEDIATE 'SELECT * FROM t WHERE id=:b' INTO v_rec USING v_id |
EXECUTE IMMEDIATE qry INTO v1, v2 USING ... | SELECT * 但 INTO 只有兩個變量 | INTO 變量數/類型與 SELECT 列一一對應 |
TYPE t_tab IS TABLE OF t_djjcxx%ROWTYPE;
l_tab t_tab;
EXECUTE IMMEDIATE 'SELECT * FROM ' || l_table_name || ' WHERE jh = :b'
BULK COLLECT INTO l_tab USING l_jh;
FOR i IN 1..l_tab.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(l_tab(i).zyq);
END LOOP;
PROCEDURE get_data(p_jh IN VARCHAR2, p_rc OUT SYS_REFCURSOR) IS
v_sql VARCHAR2(200);
BEGIN
v_sql := 'SELECT * FROM dynamic_tbl WHERE jh = :b';
OPEN p_rc FOR v_sql USING p_jh;
END;
適用於報表工具/中間件需要游標句柄的場景。