編寫預存程序時,動態組合的大型 SQL (如超過 32767 字元、多表 Join、複雜條件) 無法在 PL/SQL Developer 等工具的「Test」視窗直接檢視。本文提供一招實用技巧:利用 DBMS_OUTPUT.PUT_LINE 將組合完成的 SQL 字串輸出至除錯視窗,快速驗證語法與邏輯。
CREATE OR REPLACE PROCEDURE proc_complex_query IS
v_sql CLOB; -- 或 VARCHAR2(32767)
BEGIN
-- 動態組合 SQL
v_sql := 'SELECT ... FROM ... WHERE ...'; -- 複雜邏輯拼接
-- 【關鍵步驟】輸出完整 SQL 供檢視
DBMS_OUTPUT.PUT_LINE('=== Generated SQL ===');
DBMS_OUTPUT.PUT_LINE(v_sql);
DBMS_OUTPUT.PUT_LINE('=====================');
-- 執行動態 SQL (範例)
-- EXECUTE IMMEDIATE v_sql;
-- 或 OPEN cursor FOR v_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
RAISE;
END;
/
DBMS_OUTPUT.PUT_LINE(...) 輸出 SQL 變數。DBMS_OUTPUT 單行限制 32767 字元 (12c+ 可至 1M),超長 SQL 需分段:
FOR i IN 1..CEIL(LENGTH(v_sql)/32000) LOOP
DBMS_OUTPUT.PUT_LINE(SUBSTR(v_sql, (i-1)*32000+1, 32000));
END LOOP;
DBMS_OUTPUT.PUT_LINE('Bind: p_dept_id=' || p_dept_id || ', p_date=' || p_date);
DEBUG_FLAG 控制,避免效能與安全風險。| 方法 | 優點 | 缺點 |
|---|---|---|
| DBMS_OUTPUT | 簡單、即時、無額外物件 | 輸出長度限制、正式環境需移除 |
| 寫入臨時表/日誌表 | 持久化、可查歷史、無長度限制 | 需建表、管理清理、稍繁瑣 |
| DBMS_DEBUG / IDE 除錯器 | 斷點、單步、變數監看 | 設定複雜、部分需權限、動態 SQL 仍難檢視完整文本 |
| SQL_TRACE + TKPROF | 完整執行統計、執行計畫 | 事後分析、非即時、輸出龐大 |
「印出 SQL 看內容」是動態 SQL 開發最朴素也最有效的除錯手法。善用 DBMS_OUTPUT,讓看不見的 SQL 變可見,修正語法錯誤、優化執行計畫、驗證參數綁定,事半功倍。