PL/SQL(Oracle)與 T-SQL(SQL Server)同屬 SQL 程序化擴展,但架構理念迥異。PL/SQL 採用嚴格的區塊結構:
DECLARE -- 宣告區(可選)
BEGIN -- 執行區(必須)
EXCEPTION -- 異常處理區(可選)
END; -- 結束標記
T-SQL 則較自由,無固定區塊界限,變量宣告混雜於執行邏輯中。
| 項目 | PL/SQL | T-SQL |
|---|---|---|
| 宣告關鍵字 | 變量名 類型 [NOT NULL] := 值 | DECLARE @變量名 類型 = 值 |
| 範例 | age NUMBER(8) := 26; | DECLARE @age INT = 26; |
mydate user.testtable.currentdate%TYPE;mytable testtable%ROWTYPE; -- 包含 testtable 所有欄位TYPE emp_rec IS RECORD (
empno NUMBER(4),
ename VARCHAR2(20),
sal NUMBER(7,2)
);
v_emp emp_rec;TYPE arr_type IS TABLE OF VARCHAR2(20) INDEX BY BINARY_INTEGER;
v_arr arr_type;
v_arr(1) := '大學'; v_arr(2) := '大專';TYPE multi_arr IS TABLE OF testtable%ROWTYPE INDEX BY BINARY_INTEGER;
v_multi multi_arr;
SELECT * INTO v_multi(60) FROM testtable WHERE recordnumber = 60;PL/SQL IF-THEN-ELSIF-ELSE-END IF 結構嚴謹,需以 END IF 閉合。T-SQL 使用 IF-BEGIN-END 配合 ELSE。
| 類型 | PL/SQL 語法 | 特點 |
|---|---|---|
| 基本 LOOP | LOOP ... EXIT WHEN 條件; END LOOP; | 至少執行一次,靈活控制退出 |
| WHILE LOOP | WHILE 條件 LOOP ... END LOOP; | 先判斷再執行 |
| FOR LOOP | FOR i IN [REVERSE] 下限..上限 LOOP ... END LOOP; | 計數器自動管理,支援反向 |
| 游標 FOR LOOP | FOR rec IN cursor_name LOOP ... END LOOP; | 隱式 OPEN/FETCH/CLOSE,最簡潔 |
COMMIT:提交交易,釋放鎖定。ROLLBACK:回滾至上一 Commit 或 Savepoint。SAVEPOINT name / ROLLBACK TO name:部分回滾。SET AUTOCOMMIT ON/OFF(SQL*Plus 環境指令)。T-SQL 預設自動提交,需以 BEGIN TRANSACTION 顯式開啟。
T-SQL 無顯式游標概念,結果集直接返回客戶端。PL/SQL 顯式游標四步驟:
CURSOR c_name IS SELECT ...OPEN c_name;FETCH c_name INTO var1, var2... | record_var;CLOSE c_name;游標屬性(%FOUND、%NOTFOUND、%ROWCOUNT、%ISOPEN)提供精細控制。
CREATE OR REPLACE PROCEDURE proc_name (
p_in IN VARCHAR2, -- 唯讀輸入
p_out OUT NUMBER, -- 唯寫輸出
p_inout IN OUT DATE -- 雙向傳遞
) AS
BEGIN ... END;
呼叫方式:BEGIN proc_name(v1, v2, v3); END;。T-SQL 使用 OUTPUT 關鍵字標記輸出參數。
PL/SQL 支援系統預定義異常(如 NO_DATA_FOUND)與自訂異常:
DECLARE
salary_err EXCEPTION;
v_sal NUMBER;
BEGIN
SELECT sal INTO v_sal FROM emp WHERE empno = 7566;
IF v_sal < 900 OR v_sal > 2600 THEN RAISE salary_err; END IF;
EXCEPTION
WHEN salary_err THEN DBMS_OUTPUT.PUT_LINE('薪資超出範圍');
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('其他錯誤:'||SQLERRM);
END;
T-SQL 使用 TRY...CATCH 區塊,錯誤資訊透過 ERROR_NUMBER() 等函數取得。
PL/SQL 側重伺服器端程序化邏輯,提供豐富的複合類型、游標、異常體系,適合複雜業務封裝;T-SQL 側重集合操作與查詢優化,語法較輕量。跨平台遷移時,需重點處理變量作用域、游標邏輯、交易邊界與異常流程的重構。