替代變數讓 SQL 語句在執行時動態接收使用者輸入,實現互動式查詢與腳本參數化。本文系統整理 &、&&、DEFINE/UNDEFINE、ACCEPT 等指令用法、資料型別處理、多變數應用、提示自訂與最佳實踐。
-- 數值型:直接輸入數字
SELECT ename, job, sal, hiredate FROM emp WHERE sal > &input_sal;
-- 字串型:需自行加單引號 (不便)
SELECT * FROM emp WHERE ename = '&input_ename';
-- 改良:利用 UPPER 自動加引號並統一大小寫
SELECT * FROM emp WHERE ename = UPPER('&input_ename');
執行時:SQL Developer 彈出輸入對話框;SQL*Plus 命令列提示 Enter value for input_ename:。
| 場景 | 語法範例 |
|---|---|
| LIKE 模糊查詢 | WHERE ename LIKE '%&keyword%' |
| 日期比較 | WHERE hiredate < TO_DATE('&input_date', 'YYYY-MM-DD') |
| 多變數組合 | WHERE job = UPPER('&input_job') AND sal > &input_sal (依序提示兩次) |
| SELECT 列動態 | SELECT &cols FROM emp |
| FROM 表動態 | SELECT * FROM &table_name |
| ORDER BY 動態 | ORDER BY &sort_col |
| GROUP BY 動態 | SELECT &grp_col, SUM(sal) FROM emp GROUP BY &grp_col |
解決 GROUP BY 需重複輸入同一值的問題:
SELECT &&grp_col, SUM(sal), AVG(sal)
FROM emp
GROUP BY &&grp_col;
第一次提示輸入 grp_col,第二次自動復用。變數生命週期至 Session 結束或執行 UNDEFINE grp_col。
-- 定義變數 (無提示,直接賦值)
DEFINE input_dname = 'ACCOUNTING'
-- 查詢已定義變數
DEFINE input_dname
-- 使用 (前綴 &)
SELECT * FROM dept WHERE dname = '&input_dname';
-- 清除變數
UNDEFINE input_dname
語法:ACCEPT var_name [TYPE] [FORMAT fmt] [PROMPT 'text'] [HIDE]
| 選項 | 功能 | 範例 |
|---|---|---|
NUMBER | 限制輸入數值 | ACCEPT v_sal NUMBER PROMPT '輸入薪資:' |
VARCHAR2 | 字串 (預設) | ACCEPT v_name VARCHAR2 PROMPT '姓名:' |
DATE | 日期,搭配 FORMAT | ACCEPT v_date DATE FORMAT 'YYYY-MM-DD' PROMPT '日期:' |
FORMAT | 格式遮罩 (如 A10、9.99) | ACCEPT v_amt NUMBER FORMAT '999,999.99' |
PROMPT | 自訂提示文字 | PROMPT '請輸入員工編號:' |
HIDE | 密碼模式 (不顯示輸入) | ACCEPT v_pwd VARCHAR2 HIDE PROMPT '密碼:' |
query_emp.sql)ACCEPT v_empno NUMBER PROMPT '輸入員工編號: '
ACCEPT v_hiredate DATE FORMAT 'YYYY-MM-DD' PROMPT '入職日期 (YYYY-MM-DD): '
SELECT empno, ename, job, hiredate
FROM emp
WHERE empno = &v_empno
AND hiredate = TO_DATE('&v_hiredate', 'YYYY-MM-DD');
執行:SQL> @query_emp.sql
UPPER('&var')**,避免大小寫與引號困擾。.sql 副檔名,SQL*Plus 直接 @filename 執行。DEFINE 或外部傳參 (SQLPLUS user/pwd @script.sql arg1 arg2 → 腳本內用 &1 &2)。ACCEPT ... HIDE,勿硬編碼在腳本中。UNDEFINE,避免變數殘留干擾後續腳本。