首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 動態 SQL EXECUTE IMMEDIATE ... INTO 正確用法與常見陷阱

     編輯:Oracle 資料庫相關知識

正確範例:單行查詢綁定變量

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;
/

關鍵規則 (紅框強調)

  1. 動態 SQL 字符串中不能包含 INTO 子句 — query_stmt 僅含 SELECT ... FROM ... WHERE ...,INTO 放在 EXECUTE IMMEDIATE 之後。
  2. 綁定變量佔位符用冒號前綴 — :l_jh,USING 子句按順序傳遞值。
  3. INTO 目標變量類型與 SELECT 列結構完全匹配 — 推薦用 %ROWTYPE 或 RECORD 類型,避免列數/類型不匹配。
  4. 單行查詢才能用 INTO — 多行需用 BULK COLLECT INTO 集合或 OPEN ... FOR 游標。

常見錯誤寫法對比

錯誤寫法問題正確寫法
EXECUTE IMMEDIATE 'SELECT col INTO v FROM t' USING ...動態串包含 INTOEXECUTE 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 列一一對應

進階:多行動態查詢 (BULK COLLECT)

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;

進階:動態 REF CURSOR 返回給客戶端

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;

適用於報表工具/中間件需要游標句柄的場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved