CodeGym /課程 /SQL SELF /在有約束的資料表中插入資料: NOT NULL、 DEFAULT

在有約束的資料表中插入資料: NOT NULL、 DEFAULT

SQL SELF
等級 21, 課堂 1
開放

今天我們要仔細聊聊資料庫操作裡一個很重要的點——怎麼在有 NOT NULL 跟 DEFAULT 約束的資料表裡插入資料。你現在應該已經會用 INSERT INTO 的基本語法,也知道怎麼往有特定結構的資料表加資料。現在是時候深入一點了——因為處理這些約束常常讓開發者頭很痛。不過別擔心,這堂課結束你就能很順地搞定這些機制啦!

什麼是約束?

約束就是加在資料表欄位上的規則。它們幫你確保資料是合邏輯的。比如說,有些欄位不能留空(NOT NULL),或者你可以不填某個欄位,因為它有預設值(DEFAULT)。

約束的種類: - NOT NULL — 表示這個欄位不能是 NULL。 - DEFAULT — 設定如果沒填這個欄位時,自動用這個值。

約束可以幫你維護資料完整性。想像一下,你有個 students 的資料表,規定每個學生一定要有名字(NOT NULL)。如果沒有這個約束,有人忘記填名字,資料庫裡就會出現「沒名字的學生」。再舉個例子:你決定新課程的學分預設是 0(DEFAULT),這樣每次不用自己填。

怎麼用 NOT NULL 約束

NOT NULL 這個約束會強制你在新增資料時一定要填這個欄位。如果你想塞 NULL 或根本沒填,資料庫就會「生氣」(出錯)。來看個例子。

我們先建立一個簡單的 students 資料表:

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,     -- 名字不能是空的
    age INT
);

注意:name 欄位有 NOT NULL 約束,age 就沒有。

插入有 NOT NULL 約束的資料範例

現在來加幾個學生:

-- 成功插入的例子
INSERT INTO students (name, age) VALUES ('Alice', 23);
-- 成功:有填名字,符合 NOT NULL 約束

-- 出錯的例子:
INSERT INTO students (age) VALUES (30);
-- 錯誤:name 欄位不能是 NULL,因為有 NOT NULL 約束

如果你看到像 null value in column "name" violates not-null constraint 這種錯誤,不用怕——這只是 PostgreSQL 提醒你要小心點。

怎麼用預設值(DEFAULT)

DEFAULT 約束就是跟資料庫說:「如果有人忘記填這個欄位,就用這個預設值吧」。這樣開發者就不用每次都手動填。

有 DEFAULT 約束的資料表範例

我們來建立一個 courses 資料表:

CREATE TABLE courses (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    credits INT DEFAULT 0   -- credits 欄位的預設值是 0
);

插入有 DEFAULT 約束的資料範例

現在來加幾個課程:

-- 有明確填 credits
INSERT INTO courses (name, credits) VALUES ('Mathematics', 5);

-- 沒填 credits,會用預設值(0)
INSERT INTO courses (name) VALUES ('History');

-- 來看看結果
SELECT * FROM courses;

結果:

id name credits
1 Mathematics 5
2 History 0

注意:加 History 這門課時沒填學分,PostgreSQL 自動幫你把 credits 欄位設成 0。

同時用 NOT NULL 跟 DEFAULT 約束

這種欄位就算你沒填值也一定會有值。像 courses 資料表的 credits 欄位就可以同時有 DEFAULT 跟 NOT NULL,這樣就能保證沒人會不小心留空 NULL。

CREATE TABLE courses (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    credits INT NOT NULL DEFAULT 0
);

插入資料範例

假設每個新課程預設學分是 0,但不能是 NULL。

-- 成功:credits 用預設值
INSERT INTO courses (name) VALUES ('Physics');

-- 錯誤:credits 明確塞 NULL,但有 NOT NULL 約束
INSERT INTO courses (name, credits) VALUES ('Chemistry', NULL);

範例:加一個一定要有名字的學生

我們來建立一個有約束的 students 資料表:

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,                         -- 名字一定要填
    enrollment_date DATE DEFAULT CURRENT_DATE   -- 入學日期預設是今天
);

現在來加學生:

-- 有填名字,入學日期自動填
INSERT INTO students (name) VALUES ('Bob');

-- 試著不填名字(會出錯)
INSERT INTO students (enrollment_date) VALUES ('2024-10-01');

這就是 PostgreSQL 幫你確保資料正確的好例子:每個學生一定有名字,入學日期不用自己填。

小技巧跟「地雷」

你在用 NOT NULL 跟 DEFAULT 這些約束時,有幾個重點要記得。比如說,如果你的資料常常會有 NULL,那 NOT NULL 可能會讓你很頭大。還有,如果每個欄位都設預設值,有時候會不小心塞進不正確的資料(像是 0 取代真實值)。

通常你在現有資料表加新欄位時,舊資料的這個欄位會是 NULL。但如果你有設 DEFAULT X,整個欄位就會自動填 X。這超方便,也能幫你維護資料庫完整性。

舉例來說,新欄位是指向另一個資料表的 FOREIGN KEY。它不能是 NULL 或 0,一定要連到已經存在的資料。

如果忘記加約束怎麼辦?

別擔心——你隨時可以用 ALTER TABLE 指令補上約束。像這樣:

-- 幫現有欄位加 DEFAULT 約束
ALTER TABLE courses ALTER COLUMN credits SET DEFAULT 0;

-- 幫現有欄位加 NOT NULL 約束
ALTER TABLE students ALTER COLUMN name SET NOT NULL;

這些指令不會破壞你現有的資料——你可以很放心地在已經有資料的表上用。

現在你已經準備好用 PostgreSQL 的威力來管理約束啦!你的資料會更有結構、更不容易出錯,查詢也會更有邏輯、更好預測。

2
任務
SQL SELF, 等級 21, 課堂 1
上鎖
同時使用 `NOT NULL` 和 `DEFAULT`
同時使用 `NOT NULL` 和 `DEFAULT`
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION