CodeGym /課程 /SQL SELF /PL/pgSQL 資料型別及其用法:INTEGER、TEXT、BOOLEAN、RECORD

PL/pgSQL 資料型別及其用法:INTEGER、TEXT、BOOLEAN、RECORD

SQL SELF
等級 49 , 課堂 4
開放

這堂課我們會看看 PL/pgSQL 支援哪些資料型別,還有怎麼有效率地用它們。我們會重點介紹四種資料型別:

  • INTEGER 用來處理數字。
  • TEXT 處理字串。
  • BOOLEAN 處理邏輯值。
  • RECORD 處理動態資料結構。

每個型別我們都會用範例來說明,讓你看到實際怎麼用。

PL/pgSQL 支援的資料型別

PL/pgSQL 支援你在 PostgreSQL 裡熟悉的所有資料型別。從簡單的數字型別(INTEGERNUMERIC)到比較複雜的像陣列和 JSONB。我們來快速看一下主要的型別。

  1. 基本型別:

    • INTEGERBIGINTFLOATNUMERIC — 數字型別。
    • TEXTCHARVARCHAR — 字串型別。
    • BOOLEAN — 邏輯型別。
  2. 複雜型別:

    • RECORD — 處理動態資料集。
    • ROWTYPE — 處理資料表 row 型別。
    • 陣列跟 JSON — 之後課程會再講。

怎麼用 INTEGER 型別

INTEGER 是最常用的資料型別之一,用來存整數。在 PL/pgSQL 裡你可以用這型別來做計算、處理資料的 id、還有判斷條件。

範例:計算資料筆數

假設我們有一個 students 資料表,想知道有幾個學生在資料庫裡。

DO $$
DECLARE
    total_students INTEGER; -- 用來存學生數量的變數
BEGIN
    SELECT COUNT(*) INTO total_students FROM students; -- 把查詢結果存進變數
    RAISE NOTICE '學生數量:%', total_students; -- 印出訊息
END;
$$;

INTEGER 時要注意:

  • 在 PL/pgSQL 裡,變數賦值要用 INTO
  • 如果你想把小數存進 INTEGER,會出錯。這種情況要用 NUMERICFLOAT

怎麼用 TEXT 型別

TEXT 用來存字串資料。像是名字、描述或其他文字內容都很適合用這型別。

範例:印出學生名字

這個範例會把 students 資料表裡所有學生的名字印出來。

DO $$
DECLARE
    student_name TEXT; -- 存學生名字的變數
BEGIN
    FOR student_name IN SELECT name FROM students LOOP
        RAISE NOTICE '學生名字:%', student_name; -- 印出每個名字
    END LOOP;
END;
$$;

處理 TEXT 很實用的函數:

  • UPPER()LOWER() — 轉成大寫/小寫。
  • CONCAT() — 字串合併。
  • LENGTH() — 字串長度。

舉個例子:

DO $$
DECLARE
    full_name TEXT;
BEGIN
    full_name := CONCAT('阿歷克斯', ' 明'); -- 合併字串
    RAISE NOTICE '全名:%', UPPER(full_name); -- 印出大寫名字
END;
$$;

怎麼用 BOOLEAN 型別

BOOLEAN 用來存邏輯值:TRUEFALSENULL。這型別在判斷條件和資料篩選時超好用。

範例:檢查學生是否啟用

假設你有個 students 資料表,裡面有個 is_active 欄位,表示學生是不是啟用狀態。

DO $$
DECLARE
    is_active BOOLEAN; -- 存啟用狀態的變數
BEGIN
    SELECT is_active INTO is_active FROM students WHERE id = 1; -- 從資料表拿值
    IF is_active THEN
        RAISE NOTICE '學生是啟用的!';
    ELSE
        RAISE NOTICE '學生沒啟用。';
    END IF;
END;
$$;

BOOLEAN 時要注意:

  • 邏輯值可以直接用在 IFWHILE 條件裡。
  • NULL 在邏輯判斷裡是「未定義」,所以檢查時要小心。

怎麼用 RECORD 型別

RECORD 是很強大的型別,用來存沒有預先定義結構的資料 row。當你處理 SQL 查詢結果有多個欄位時,這型別超方便。

範例:走訪資料表所有資料

下面這個範例會走訪 students 資料表的每一筆資料,印出每個學生的名字和 ID。

DO $$
DECLARE
    student RECORD; -- 動態 row 型別
BEGIN
    FOR student IN SELECT id, name FROM students LOOP
        RAISE NOTICE 'ID:%,名字:%', student.id, student.name; -- 取出欄位
    END LOOP;
END;
$$;

RECORD 時要注意:

  • RECORD 型別的變數只能在迴圈裡或用 SELECT INTO 查詢時填值。
  • 欄位要用 record.column_name 來取。

ROWTYPE 處理整個資料表 row

如果你想把整個資料表的一筆資料存下來(而且想要明確型別),可以用 ROWTYPE。它會自動繼承資料表 row 的結構。

範例:用 ROWTYPE 型別

DO $$
DECLARE
    student students%ROWTYPE; -- 跟 students 資料表 row 結構一樣的變數
BEGIN
    SELECT * INTO student FROM students WHERE id = 1; -- 把 row 資料存進變數
    RAISE NOTICE '學生名字:%,課程:%', student.name, student.course;
END;
$$;

RECORDROWTYPE 的差異

特性 RECORD ROWTYPE
欄位結構 事先沒定義 依資料表或查詢而定
用途 彈性,什麼查詢都能用 結構固定,跟資料表綁定

實戰範例

我們來寫個函數,回傳啟用中的學生數量和他們的名字。

CREATE FUNCTION active_students_report() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY
    SELECT id, name FROM students WHERE is_active = TRUE;
END;
$$ LANGUAGE plpgsql;

呼叫這個函數:

SELECT * FROM active_students_report();

用資料型別時常見錯誤

有時候處理資料會遇到錯誤,這裡列幾個常見的:

  • 型別錯誤:像把字串存進 INTEGER 變數(例如 my_var := 'abc';)。
  • 在需要 TRUEFALSE 的地方用了 NULL
  • 沒初始化就用 RECORD

怎麼避免這些錯誤:

  • 變數型別一定要明確寫出來。
  • 寫入前先檢查資料表欄位的型別。
  • 多用 RAISE NOTICE 這種 debug 指令。

現在你已經知道怎麼在 PL/pgSQL 裡用 INTEGERTEXTBOOLEANRECORD 這些資料型別了。這些知識會讓你寫出更強大、更複雜的 PostgreSQL 程序語言程式!

1
問卷/小測驗
PL/pgSQL 入門,等級 49,課堂 4
未開放
PL/pgSQL 入門
PL/pgSQL 入門
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION