第 章 動態SQL
為何使用動態SQL
實現動態SQL有兩種方式DBMS_SQL和本地動態SQL(EXECUTE IMMEIDATE)
主要從以下方面考慮使用哪種方式
是否知道涉及的列數和類型
DBMS_SQL包括了一個可以描述結果集的存儲過程(DBMS_SQLDESCRIBE_COLUMNS)而本地動態SQL沒有
是否知道可能涉及的綁定變量數和類型
DBMS_SQL允許過程化的綁定語句的輸入而本地動態SQL需要在編譯時確定
是否使用數組化操作(Array Processing)
DBMS_SQL允許而本地動態SQL基本不可以但可以用其他方式實現(對查詢可用FETCH BULK COLLECT INTO對INSERT等可用一個BEGIN … END塊中加循環實現)
是否在同一個會話中多次執行同一語句
DBMS_SQL可以分析一次執行多次而本地動態SQL會在每次執行時進行軟分析
是否需要用REF CURSOR返回結果集
僅本地動態SQL可用REF CURSOR返回結果集
如何使用動態SQL
DBMS_SQL
調用OPEN_CURSOR獲得一個游標句柄
調用PARSE分析語句一個游標句柄可以用於多條不同的已分析語句但一個時間點僅一條有效
調用BIND_VARIABLE或BIND_ARRAY來提供語句的任何輸入
若是一個查詢(SELECT語句)調用DIFINE_COLUMN或DEFINE_ARRAY來告知Oracle如何返回結果
調用EXECUTE執行語句
若是一個查詢調用FETCH_ROWS來讀取數據可以使用COLUMN_VALUE從SELECT列表根據位置獲得這些值
否則若是一個PL/SQL塊或帶有RETURN子句的DML語句可以調用VARIABLE_VALUE從塊中根據變量名獲得OUT值
調用CLOSE_CURSOR
注意這裡對任何異常都應該處理以關閉游標防止洩露資源
本地動態SQL
EXECUTE IMMEDIATE 語句
[INTO {變量 變量 … 變量N | 記錄體}]
[USING [IN | OUT | IN OUT] 綁定變量 … 綁定變量N]
[{RETURNING | RETURN} INTO 輸出 [ … 輸出N]…]
注意本地動態SQL僅支持弱類型REF CURSOR即對於REF CURSOR不支持BULK COLLECT
最後說明
動態SQL的負面破壞了依賴鏈代碼更脆弱很難調優
From:http://tw.wingwit.com/Article/program/Oracle/201311/18948.html