ฉันจะเพิ่มคอลัมน์ในฐานข้อมูล Postgresql ที่ไม่อนุญาตให้มีค่าว่างได้อย่างไร


243

ฉันเพิ่มคอลัมน์ "ไม่เป็นโมฆะ" ใหม่ลงในฐานข้อมูล Postgresql ของฉันโดยใช้แบบสอบถามต่อไปนี้ (ฆ่าเชื้อสำหรับอินเทอร์เน็ต):

ALTER TABLE mytable ADD COLUMN mycolumn character varying(50) NOT NULL;

ทุกครั้งที่ฉันเรียกใช้แบบสอบถามนี้ฉันได้รับข้อความแสดงข้อผิดพลาดต่อไปนี้:

ERROR:  column "mycolumn" contains null values

ฉันนิ่งงัน ฉันจะไปไหนผิด

หมายเหตุ: ฉันใช้ pgAdmin III (1.8.4) เป็นหลัก แต่ฉันได้รับข้อผิดพลาดเดียวกันเมื่อฉันรัน SQL จากภายในเทอร์มินัล

คำตอบ:


400

คุณต้องตั้งค่าเริ่มต้น

ALTER TABLE mytable ADD COLUMN mycolumn character varying(50) NOT NULL DEFAULT 'foo';

... some work (set real values as you want)...

ALTER TABLE mytable ALTER COLUMN mycolumn DROP DEFAULT;

1
ทางออกที่ดี ฉันไม่สามารถไปที่ postgres เอกสารออนไลน์ด้วยเหตุผลบางอย่างเพื่อดูว่าไวยากรณ์นี้จะเป็นอย่างไร
30732 Sean ฌอนสดใส

4
@SeanBright คุณสามารถเข้าถึง postgres doc ออฟไลน์ได้โดยทำman ALTER_TABLE :)
allan.simon

@ allan.simon ฉันไม่เคยใช้ PostgreSQL มาก่อนและฉันไม่ได้ติดตั้งไว้ที่ใดเลย
Sean Bright

2
ในการชี้แจง: ค่าเริ่มต้นจำเป็นสำหรับการอัพเดตแถวที่มีอยู่เท่านั้นซึ่งเป็นสาเหตุที่ทำให้สามารถลบทิ้งได้ทันทีหลังจากนั้น แถวที่มีอยู่ทั้งหมดได้รับการปรับปรุงเมื่อมีการเปลี่ยนแปลงตาราง (ซึ่งอาจใช้เวลาสักครู่ชัด)
MSalters

2
สิ่งนี้จะไม่ทำงานหากคุณต้องการใช้คอลัมน์อื่นเพื่อคำนวณค่าเริ่มต้นสำหรับแถวที่มีอยู่ คำตอบของ j_random_hackerทำให้มีความแข็งแกร่งขึ้น
jpmc26

82

ดังที่คนอื่น ๆ สังเกตคุณต้องสร้างคอลัมน์ที่สามารถ nullable หรือระบุค่า DEFAULT หากนั่นไม่ยืดหยุ่นเพียงพอ (เช่นหากคุณต้องการคำนวณค่าใหม่สำหรับแต่ละแถวทีละอย่าง) คุณสามารถใช้ความจริงที่ว่าใน PostgreSQL คำสั่ง DDL ทั้งหมดสามารถดำเนินการภายในธุรกรรม:

BEGIN;
ALTER TABLE mytable ADD COLUMN mycolumn character varying(50);
UPDATE mytable SET mycolumn = timeofday();    -- Just a silly example
ALTER TABLE mytable ALTER COLUMN mycolumn SET NOT NULL;
COMMIT;

7
แม้ในธุรกรรมไม่บังคับใช้ NULL ทันทีดังนั้นต้องเพิ่มคอลัมน์เติมค่าแล้วเพิ่ม NOT NULL - ตามที่คำตอบนี้ทำ (ทดสอบกับ postgres 9.6)
Beni Cherniavsky-Paskin

48

เนื่องจากแถวมีอยู่แล้วในตารางALTERคำสั่งพยายามแทรกNULLลงในคอลัมน์ที่สร้างขึ้นใหม่สำหรับแถวที่มีอยู่ทั้งหมด คุณจะต้องเพิ่มคอลัมน์ตามที่อนุญาตNULLจากนั้นเติมคอลัมน์ด้วยค่าที่คุณต้องการจากนั้นตั้งค่าให้เป็นNOT NULLภายหลัง


7
ตัวอย่างของวิธีการที่จะทำได้ดีจริงๆ มิฉะนั้นโซลูชันของ Luc น่าจะสมบูรณ์และพร้อมใช้งานมากขึ้น
Victor Farazdagi

5

คุณต้องกำหนดค่าเริ่มต้นหรือทำในสิ่งที่ Sean พูดและเพิ่มเข้าไปโดยไม่มีข้อ จำกัด null จนกว่าคุณจะเติมลงในแถวที่มีอยู่


2

การระบุค่าเริ่มต้นจะใช้ได้เช่นกันโดยสมมติว่าค่าเริ่มต้นเหมาะสม


2
มันจะปรับปรุงคำตอบเพื่อให้ไวยากรณ์ที่แก้ไขเพิ่มเติมเพื่อสร้างคอลัมน์ที่มีค่าเริ่มต้น (สำหรับภาพประกอบ)
hardmath

1

หรือสร้างตารางใหม่เป็น temp ด้วยคอลัมน์พิเศษคัดลอกข้อมูลไปยังตารางใหม่นี้ในขณะที่จัดการมันตามความจำเป็นเพื่อเติมคอลัมน์ใหม่ที่ไม่สามารถลบล้างได้จากนั้นสลับตารางผ่านการเปลี่ยนชื่อสองขั้นตอน

ใช่มันมีความซับซ้อนมากขึ้น แต่คุณอาจต้องทำเช่นนี้หากคุณไม่ต้องการการอัปเดตที่ยิ่งใหญ่บนตารางสด


3
ฉันไม่ได้เป็นคุณ -1 แต่ฉันคิดว่าอาจมีปัญหาเล็กน้อยเกี่ยวกับเรื่องนี้ - เช่นฉันเดิมพันว่าดัชนีที่มีอยู่ทริกเกอร์และมุมมองที่มีอยู่จะยังคงอ้างอิงตารางต้นฉบับต่อไปแม้ว่าจะเปลี่ยนชื่อตามที่ฉันคิดว่าพวกเขาเก็บ relid ของตาราง (ซึ่งไม่เปลี่ยนแปลง) มากกว่าชื่อ
j_random_hacker

1
ใช่ฉันควรระบุว่าตารางใหม่ควรเป็นสำเนาที่แน่นอนของต้นฉบับรวมถึงการเพิ่มดัชนีและสิ่งอื่น ๆ ฉันไม่ดีที่สั้นเกินไป เหตุผลของเรื่องนี้ก็คือว่ายังมีความสลับซับซ้อนเล็กน้อยในการเล่น ALTER บนโต๊ะที่อาจมีชีวิตอยู่และบางครั้งคุณจำเป็นต้องแสดงบนเวที
alphadogg

ตัวอย่างเช่นการใช้วิธีการเริ่มต้นคุณจะเพิ่มค่าเริ่มต้นนั้นในแต่ละแถว ไม่แน่ใจว่า Postgres ล็อกตารางอย่างไรเมื่อทำสิ่งนี้ หรือหากการเรียงลำดับคอลัมน์มีความสำคัญคุณจะไม่สามารถเพิ่มคอลัมน์ด้วยคำสั่ง ALTER ได้
alphadogg

ยุติธรรมเพียงพอ ALTER TABLE จะล็อคตารางตามเอกสาร PostgreSQL อย่างไรก็ตามวิธีการที่ไม่ทำธุรกรรมของคุณมีความเสี่ยงที่จะสูญเสียการเปลี่ยนแปลงหากตารางนั้นใช้งานได้จริง นอกจากนี้ฉันขอแนะนำให้ใช้รหัสใด ๆ ที่ขึ้นอยู่กับลำดับของคอลัมน์เสีย (ซึ่งอาจอยู่นอกเหนือการควบคุมของคุณแน่นอน)
j_random_hacker

2
วิธีการนี้ยังเป็นปัญหาโดยเฉพาะอย่างยิ่งหากตารางถูกอ้างอิงโดยดัชนีคีย์ต่างประเทศเนื่องจากจะต้องสร้างใหม่เช่นกัน
Aryeh Leib Taurog

0

แบบสอบถามนี้จะอัปเดต nulls โดยอัตโนมัติ

ALTER TABLE mytable ADD COLUMN mycolumn character varying(50) DEFAULT 'whatever' NOT NULL;

-6

สิ่งนี้ใช้ได้กับฉัน: :)

ALTER TABLE your_table_name ADD COLUMN new_column_name int;

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