นิยามคอลัมน์ SQL: ค่าเริ่มต้นและไม่ซ้ำซ้อน null?


88

ฉันเคยเห็นไวยากรณ์ต่อไปนี้หลายครั้งซึ่งกำหนดคอลัมน์ในคำสั่งสร้าง / แก้ไข DDL:

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"

คำถามคือเนื่องจากมีการระบุค่าดีฟอลต์จึงจำเป็นต้องระบุด้วยว่าคอลัมน์ไม่ควรยอมรับ NULL หรือไม่ กล่าวอีกนัยหนึ่งค่า DEFAULT ไม่ทำให้ซ้ำซ้อน NOT NULL?

คำตอบ:


133

DEFAULTคือค่าที่จะถูกแทรกในกรณีที่ไม่มีค่าที่ชัดเจนในคำสั่ง insert / update สมมติว่า DDL ของคุณไม่มีNOT NULLข้อ จำกัด :

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT 'MyDefault'

จากนั้นคุณสามารถออกแถลงการณ์เหล่านี้ได้

-- 1. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B) VALUES (NULL, NULL);

-- 2. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, DEFAULT);

-- 3. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B, col) DEFAULT VALUES;

-- 4. This will insert NULL into tbl.col
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, NULL);

หรือคุณสามารถใช้DEFAULTในUPDATEคำสั่งตามมาตรฐานSQL-1992 :

-- 5. This will update 'MyDefault' into tbl.col
UPDATE tbl SET col = DEFAULT;

-- 6. This will update NULL into tbl.col
UPDATE tbl SET col = NULL;

หมายเหตุฐานข้อมูลบางส่วนไม่รองรับไวยากรณ์มาตรฐาน SQL ทั้งหมดเหล่านี้ การเพิ่มNOT NULLข้อ จำกัด จะทำให้เกิดข้อผิดพลาดกับคำสั่ง4, 6ในขณะที่1-3, 5ยังเป็นคำสั่งที่ถูกต้อง ดังนั้นเพื่อตอบคำถามของคุณ: ไม่มันไม่ซ้ำซ้อน


ฉันไปที่ลิงก์ของคุณ (ไปยังบล็อกโพสต์ของคุณ) โดยคาดหวังว่าจะเห็นคำอธิบาย (อาจมีตัวเลขบางส่วน) ของผลกระทบอย่างมากต่อประสิทธิภาพการสืบค้น แต่เห็นเพียงสั้น ๆ ว่ามีผลกระทบ ไม่มีความผิด แต่ลิงค์ทำให้เข้าใจผิดเล็กน้อย
Seth Flowers

@SethFlowers: ขอบคุณสำหรับตัวชี้ Seth ในระหว่างนี้บทความที่เชื่อมโยงได้รับการแก้ไข ฉันจะดูว่าฉันสามารถเชื่อมโยงอย่างอื่นแทนหรือลบลิงก์ออก อย่างที่เป็นอยู่ตอนนี้คุณพูดถูกแล้วมันไม่ได้เพิ่มคุณค่าใด ๆ ให้กับคำตอบ
Lukas Eder

ขอบคุณ - ฉันหวังว่าฉันจะไม่ฟังดูหยาบคาย ฉันเพิ่งเห็นลิงก์และคิดว่า "ใช่นั่นคือสิ่งที่ฉันต้องการอ่าน" - จากนั้นก็ผิดหวังเล็กน้อย :)
Seth Flowers

@SethFlowers: ไม่ต้องห่วง ฉันเห็นด้วยอย่างยิ่ง เพื่อช่วยเหลือฉัน: ทักษะการเขียนบล็อกของฉันพัฒนาขึ้นอย่างมากในช่วงหลายปีที่ผ่านมา :)
Lukas Eder

19

nullถึงแม้จะมีค่าเริ่มต้นคุณก็สามารถแทนที่ข้อมูลคอลัมน์ที่มี

NOT NULLข้อ จำกัด จะไม่ยอมให้คุณปรับปรุงแถวนั้นหลังจากที่มันถูกสร้างขึ้นด้วยความnullคุ้มค่า


ฉันคิดว่าสิ่งนี้ควรได้รับการปรับปรุงใหม่: "ข้อ จำกัด NOT NULL จะไม่อนุญาตให้คุณอัปเดตแถวนั้นหลังจากสร้างด้วยค่า null" แน่นอนว่าแถวที่มีคอลัมน์ NOT NULL สามารถอัปเดตได้พวกเขาไม่สามารถอัปเดตด้วย null เป็น ค่าสำหรับคอลัมน์นั้น นอกจากนี้: ฉันคิดว่าการสร้างแถวหมายถึงการแทรกแถว คำสั่ง INSERT ไม่สามารถมีค่า null สำหรับคอลัมน์ที่ระบุด้วย NOT NULL ได้
makrom

4

ครู SQL ของฉันบอกว่าถ้าคุณระบุทั้งDEFAULTมูลค่าและNOT NULLหรือNULL, DEFAULTควรจะแสดงก่อนNOT NULLหรือNULLหรือ

แบบนี้:

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NOT NULL

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NULL


5
สวัสดีและขอบคุณที่เข้าร่วม อย่างไรก็ตามสิ่งนี้ไม่ได้ตอบคำถามที่อยู่ในมือและคำสั่งทั้งสองมีผลบังคับใช้อย่างสมบูรณ์ ฉันคิดว่ามันง่ายกว่าที่จะใส่ค่าเริ่มต้นในตอนท้ายเมื่อฉันเขียนสคริปต์ตารางด้วยตนเองเพราะค่า NULL และ NOT NULL จะจัดแนวได้ดีกว่า
emragins

โอเคฉันเดาว่าคุณพูดถูกเช่นกัน ฉันไม่เข้าใจว่าทำไมหลักสูตรของฉันถึงบอกสิ่งที่ฉันเขียนอย่างชัดเจนในคำตอบของฉัน ฉันรู้ว่าคำตอบของฉันไม่ได้ตรงกับคำถาม แต่ฉันพบว่าความคิดเห็นจะอ่านไม่ออก
Tanguy Labrador Ruiz

3
มีความแตกต่างระหว่างแนวทางปฏิบัติที่ดีที่สุด (อัตนัย) และกฎ ไม่ใช่ความคิดที่ดีที่จะมีสไตล์ที่สอดคล้องกัน แต่ในกรณีนี้โดยเฉพาะฉันไม่ต้องการเป็นโมฆะก่อนค่าเริ่มต้น ไม่ว่าคุณจะเขียนความคิดเห็นแทนคำตอบได้ด้วยก็ตามสิ่งนี้จะเหมาะสมกว่า
makrom

นั่นอาจไม่ตอบคำถาม แต่นั่นคือสิ่งที่ฉันกำลังมองหา ขอขอบคุณ.
Sasuke Uchiha

2

ฉันจะบอกว่าไม่

หากคอลัมน์ยอมรับค่า null ไม่มีอะไรที่จะหยุดคุณแทรกค่า null ลงในฟิลด์ได้ เท่าที่ฉันทราบค่าเริ่มต้นจะใช้กับการสร้างแถวใหม่เท่านั้น

หากไม่ได้ตั้งค่า null คุณจะไม่สามารถแทรกค่าว่างลงในฟิลด์ได้เนื่องจากจะทำให้เกิดข้อผิดพลาด

คิดว่ามันเป็นกลไกที่ไม่ปลอดภัยในการป้องกันโมฆะ


2
คุณพูดว่า 'สร้างกฎใหม่' คุณตั้งใจจะพูดว่า "สร้างแถวใหม่" หรือไม่
bielawski

ฉันคิดว่านั่นเป็นคำตอบที่เป็นประโยชน์มากกว่าสำหรับคำถามนี้
Noman_ibrahim

@bielawski และเกือบ 8 ปีต่อมาฉันได้แก้ไขการพิมพ์ผิดนั้น :)
Dark Hippo

นี่ควรเป็นคำตอบที่ได้รับการยอมรับ OP ถามคำถามง่ายๆและคำตอบคือ "ไม่" จำเป็นต้องมีคำอธิบายและตัวอย่างสำหรับเอกสารประกอบ
Nicolas Hevia

0

กล่าวอีกนัยหนึ่งค่า DEFAULT ไม่ทำให้ซ้ำซ้อน NOT NULL?

ไม่มันไม่ซ้ำซ้อน เพื่อขยายคำตอบที่ยอมรับ สำหรับคอลัมน์colที่มีความกลัวที่เป็นโมฆะสามารถแทรก NULL ได้แม้ว่าจะมีการกำหนด DEFAULT ไว้ก็ตาม:

CREATE TABLE t(id INT PRIMARY KEY, col INT DEFAULT 10);

-- we just inserted NULL into column with DEFAULT
INSERT INTO t(id, col) VALUES(1, NULL);

+-----+------+
| ID  | COL  |
+-----+------+
|   1 | null |
+-----+------+

Oracle แนะนำไวยากรณ์เพิ่มเติมสำหรับสถานการณ์ดังกล่าวเพื่อลบล้าง NULL ที่ชัดเจนด้วยค่าเริ่มต้นDEFAULT ON NULL:

CREATE TABLE t2(id INT PRIMARY KEY, col INT DEFAULT ON NULL 10);
-- same as
--CREATE TABLE t2(id INT PRIMARY KEY, col INT DEFAULT ON NULL 10 NOT NULL); 

INSERT INTO t2(id, col) VALUES(1, NULL);

+-----+-----+
| ID  | COL |
+-----+-----+
|  1  |  10 |
+-----+-----+

ที่นี่เราพยายามแทรก NULL แต่รับค่าเริ่มต้นแทน

db <> การสาธิตซอ

เป็นโมฆะ

หากคุณระบุอนุประโยค ON NULL ดังนั้น Oracle Database จะกำหนดค่าคอลัมน์ DEFAULT เมื่อคำสั่ง INSERT ที่ตามมาพยายามกำหนดค่าที่ประเมินเป็น NULL

เมื่อคุณระบุ ON NULL จะมีการระบุสถานะข้อ จำกัด NOT NULL และ NOT DEFERRABLE โดยปริยาย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.