在 Oracle 開發中,EXEC 與 CALL 皆可執行預存程序,但兩者適用場景、語法規則與工具相容性存在顯著差異。本文通過實測對比,為您釐清核心區別。
| 維度 | EXEC / EXECUTE | CALL |
|---|---|---|
| 本質 | SQL*Plus 專屬命令 | SQL 標準語句 |
| 適用工具 | 僅限 SQL*Plus、SQLcl | 所有支援 SQL 的客戶端(PL/SQL Developer、SQL Developer、JDBC、ODBC 等) |
| 括號規則 | 無參數時可省略括號 | 必須保留括號,無參數亦需寫 () |
| 回傳值處理 | 不支援函數回傳值接收 | 可搭配 INTO 子句接收函數回傳值 |
| 事務控制 | 隱含提交行為視工具而定 | 符合 SQL 標準事務語義 |
CREATE PROCEDURE p_test IS BEGIN NULL; END; /
SQL> EXEC p_test; PL/SQL 過程已成功完成。 SQL> CALL p_test(); 呼叫完成。 SQL> CALL p_test; ERROR at line 1: ORA-06576: not a valid function or procedure name
結論:SQL*Plus 兩者皆可用,但 CALL 必須帶括號。
-- 僅 CALL 可用 CALL p_test(); -- 成功 EXEC p_test; -- 報錯:ORA-00900: invalid SQL statement
CREATE FUNCTION f_get_date RETURN DATE IS BEGIN RETURN SYSDATE; END; / -- CALL 可接收回傳值 VARIABLE v_date VARCHAR2(30); CALL f_get_date() INTO :v_date; PRINT v_date; -- EXEC 無法直接接收函數回傳值 -- 需改用匿名區塊:EXEC :v_date := f_get_date();
CALL proc_name();,確保在 SQL*Plus、PL/SQL Dev、應用程式中皆可執行。EXEC 輸入較簡短,適合臨時測試。CALL func() INTO :bind_var; 或匿名區塊。{CALL proc_name(?)} 或 {? = CALL func()} 語法。EXEC 是 SQL 標準 → 實為 SQL*Plus 專屬命令,不可用於應用程式 SQL。CALL 的強制括號要求 → 導致 ORA-06576 錯誤。EXEC 調用函數並接收返回值 → 不支援,需改寫。EXEC 是 SQL*Plus 的便捷命令,CALL 則是標準 SQL 呼叫語句。編寫需部署至應用或多工具環境的腳本時,請優先使用 CALL 並帶上括號,以確保最大相容性。