在資料庫的世界裡,有幾種語言可以擴充一般 SQL 的功能,讓你直接在資料庫裡寫完整的商業邏輯。每種語言都針對自己的平台設計,但基本上它們的目標都差不多——自動化、簡化還有加速資料處理。這些語言包括 PostgreSQL 的 PL/pgSQL、Oracle 的 PL/SQL 以及 SQL Server 的 T-SQL。每一種都有自己的特色、優勢和小細節,現在就來聊聊這些東西。
PL/pgSQL(Procedural Language/PostgreSQL Structured Query Language)是一種整合在 PostgreSQL 裡的程序式程式語言。它的主要目標是擴充 SQL 的功能,讓開發者可以用變數、迴圈、控制結構還有錯誤處理區塊。這讓這個語言變成在資料庫端實現複雜商業邏輯的強大工具。
PL/SQL(Procedural Language/SQL)是 Oracle 資料庫內建的程序式語言。它也提供類似的資料處理能力,還能建立程序、函式和套件。PL/SQL 因為經過多年的打磨和豐富的工具生態系,被認為是很成熟的語言。
T-SQL(Transact-SQL)是 Microsoft 為 SQL Server 開發的語言。它是標準 SQL 的擴充,包含變數、控制結構和其他程序式元素。T-SQL 在交易、游標和 JSON 處理方面有自己的特色。
PL/pgSQL、PL/SQL 和 T-SQL 的相似之處
乍看之下,這三種語言其實很像。這也不奇怪,因為它們的目標都一樣——幫助開發者在資料庫裡實現商業邏輯。來看看主要的相似點:
區塊語法
三種語言都提供結構化的程序式程式碼寫法。主要元素有:
- 變數宣告。
- 主要執行區塊(
BEGIN ... END)。 - 支援例外處理。
變數
你可以在這三種語言裡宣告和使用變數。PL/pgSQL 宣告變數的範例:
DECLARE 學生_id INT; BEGIN 學生_id := 10; END;PL/SQL 和 T-SQL 也可以做一樣的事。
控制結構
所有語言都支援
IF...THEN、CASE、LOOP、FOR、WHILE,可以寫很複雜的演算法。函式與程序
可以建立和呼叫自訂的函式與程序,這些可以回傳單一值或整個表格。
PL/pgSQL、PL/SQL 和 T-SQL 的差異
開發者常常會遇到要從一個資料庫換到另一個的情況。這時候知道語言的細節就很重要了。來看看主要的差異。
變數宣告
PL/pgSQL:變數在 DECLARE 區塊裡宣告。指定值用 :=。
DECLARE
總學生數 INT;
BEGIN
總學生數 := 5;
END;
PL/SQL:宣告方式跟 PL/pgSQL 類似,但變數型別可以用 %TYPE 從資料表欄位繼承。
DECLARE
學生姓名 students.name%TYPE;
BEGIN
學生姓名 := 'John';
END;
T-SQL:變數用 DECLARE 宣告,指定值用 SET 或 SELECT。
DECLARE @總學生數 INT;
SET @總學生數 = 5; -- 或者
SELECT @總學生數 = COUNT(*) FROM students;
錯誤處理
PL/pgSQL:用 EXCEPTION 區塊處理錯誤。例如:
BEGIN
SELECT * INTO 我的變數 FROM 不存在的表;
EXCEPTION
WHEN others THEN
RAISE NOTICE '發生錯誤!';
END;
PL/SQL:也是用 EXCEPTION,但錯誤分類更細。
BEGIN
SELECT * INTO 我的變數 FROM 不存在的表;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('沒有找到資料!');
END;
T-SQL:用 TRY...CATCH 結構。
BEGIN TRY
SELECT 1/0; -- 除以零的錯誤
END TRY
BEGIN CATCH
PRINT '發生錯誤!';
END CATCH;
游標操作
PL/pgSQL:游標是隱式的,可以在迴圈裡用。
FOR row IN SELECT * FROM students LOOP
RAISE NOTICE '學生: %', row.name;
END LOOP;
PL/SQL:游標要明確宣告。例如:
DECLARE
CURSOR 學生游標 IS SELECT * FROM students;
學生資料 students%ROWTYPE;
BEGIN
OPEN 學生游標;
FETCH 學生游標 INTO 學生資料;
CLOSE 學生游標;
END;
T-SQL:游標用 CURSOR 宣告。
DECLARE 學生游標 CURSOR FOR SELECT name FROM students;
OPEN 學生游標;
FETCH NEXT FROM 學生游標;
CLOSE 學生游標;
DEALLOCATE 學生游標;
交易操作
PL/pgSQL:交易用 BEGIN、COMMIT、ROLLBACK 控制。
PL/SQL:交易也是用 COMMIT、ROLLBACK,還支援 SAVEPOINT。
T-SQL:多了 BEGIN TRANSACTION 來標記交易開始。
JSON 支援
PL/pgSQL:用 JSON 和 JSONB 資料型別強力處理 JSON。範例:
SELECT data->>'key' FROM json_table;
PL/SQL:JSON 支援比較晚才有,彈性也沒那麼高。
T-SQL:用 JSON_QUERY、JSON_VALUE 等函式處理 JSON 很方便。
什麼時候該用 PL/pgSQL、PL/SQL 或 T-SQL?
PL/pgSQL:
- 如果你的資料庫是 PostgreSQL,這就是首選。
- 很適合處理大量資料,因為支援強大的資料型別(
JSONB、陣列)。 - 開放生態系,彈性高。
PL/SQL:
- Oracle 產品的首選。
- 有豐富的資料處理生態(套件、內建程序)。
T-SQL:
- 用在 Microsoft SQL Server。
- 很適合跟 Microsoft 應用程式和 Microsoft Azure 整合。
同一個任務在 PL/pgSQL、PL/SQL 和 T-SQL 的範例
任務:計算學生數量並回傳結果
PL/pgSQL:
CREATE FUNCTION 計算學生數() RETURNS INT AS $$
DECLARE
總數 INT;
BEGIN
SELECT COUNT(*) INTO 總數 FROM students;
RETURN 總數;
END;
$$ LANGUAGE plpgsql;
PL/SQL:
CREATE OR REPLACE FUNCTION 計算學生數 RETURN NUMBER IS
總數 NUMBER;
BEGIN
SELECT COUNT(*) INTO 總數 FROM students;
RETURN 總數;
END;
T-SQL:
CREATE FUNCTION 計算學生數()
RETURNS INT
AS
BEGIN
DECLARE @總數 INT;
SELECT @總數 = COUNT(*) FROM students;
RETURN @總數;
END;
現在你大概知道 PL/pgSQL、PL/SQL 和 T-SQL 的差異了。每種語言都有自己的特色和應用場景,讓它變得獨特。語言(還有資料庫)的選擇,永遠取決於你的需求和專案的特性。
GO TO FULL VERSION