在 SQL*Plus、SQLcl、SQL Developer 執行腳本時,& 與 ' 是最常踩的兩個坑。& 預設識別替換變數,' 為字串定界符。本文系統整理三種轉義方案,並對比效能與適用場景。
SQL*Plus 內建參數 DEFINE & (hex 26) 表示 & 觸發變數替換。輸入 INSERT INTO t VALUES ('Tom & Jerry') 會提示輸入 Jerry 變數值。
SET DEFINE OFF; -- 或 SET SCAN OFF (舊版相容) -- 後續所有腳本不再解析 &,直接當作字面字元
SET DEFINE ON。SET DEFINE OFF,避免多腳本執行時狀態殘留。SELECT 'Tom' || CHR(38) || 'Jerry' FROM DUAL; -- CHR(38) = '&' 的 ASCII 碼
SELECT 'Tom' || '&' || 'Jerry' FROM DUAL; -- 實際執行兩次連接操作
Oracle 使用雙單引號表示字面單引號:'' = '。
SELECT 'Test' || '''' FROM DUAL; -- 結果:Test' -- 解析:'Test' || '' ' → 字串 + 單引號字面值
'' 代表一個單引號字元。SELECT Q'[Tom & Jerry's]' FROM DUAL; -- 直接包含 ' 和 &
SELECT Q'{It's "quoted"}' FROM DUAL; -- 括號可用 {} [] () <> 等成對符號
Q'[內容]',括號內原樣輸出,無需轉義。| 場景 | 推薦方案 | 理由 |
|---|---|---|
| SQL*Plus 執行多腳本 | SET DEFINE OFF 放腳本首行 | 零開銷、全域生效、避免狀態殘留 |
| PL/SQL 靜態字串含 & | Q'[]' 或 CHR(38) | 編譯期確定,無執行期解析風險 |
| 動態 SQL 拼接含用戶輸入 | DBMS_ASSERT.ENQUOTE_LITERAL + 繫結變數 | 防 SQL 注入、自動處理引號 |
| 匯入含大量 ' & 的資料腳本 | SET DEFINE OFF + Q'[]' | 批次處理零干擾 |
SET DEFINE OFF; DECLARE v_text VARCHAR2(4000) := Q'[User's input: "Tom & Jerry" - 100% valid]'; BEGIN INSERT INTO log_table(msg) VALUES (v_text); COMMIT; END; / -- 或使用繫結變數(最安全) VARIABLE v_msg VARCHAR2(4000); EXEC :v_msg := Q'[User's input: "Tom & Jerry" - 100% valid]'; INSERT INTO log_table(msg) VALUES (:v_msg);
SET DEFINE OFF(零成本),次選 CHR(38),避免字串拆分。Q'[]'(可讀性最強、無轉義負擔),標準雙引號 '' 為備選。