แทรกคอลัมน์ใหม่ลงในตารางใน sqlite หรือไม่


354

ผมมีตารางที่มีคอลัมน์name, ,qty rateตอนนี้ฉันต้องเพิ่มคอลัมน์ใหม่COLNewในระหว่างnameและqtyคอลัมน์ ฉันจะเพิ่มคอลัมน์ใหม่ในระหว่างสองคอลัมน์ได้อย่างไร

คำตอบ:


677

คุณมีสองตัวเลือก ก่อนอื่นคุณสามารถเพิ่มคอลัมน์ใหม่โดยทำดังนี้:

ALTER TABLE {tableName} ADD COLUMN COLNew {type};

ประการที่สองและซับซ้อนกว่า แต่จริง ๆ แล้วจะใส่คอลัมน์ที่คุณต้องการมันจะเปลี่ยนชื่อตาราง:

ALTER TABLE {tableName} RENAME TO TempOldTable;

จากนั้นสร้างตารางใหม่ด้วยคอลัมน์ที่ขาดหายไป:

CREATE TABLE {tableName} (name TEXT, COLNew {type} DEFAULT {defaultValue}, qty INTEGER, rate REAL);

และเติมด้วยข้อมูลเก่า:

INSERT INTO {tableName} (name, qty, rate) SELECT name, qty, rate FROM TempOldTable;

จากนั้นลบตารางเก่า:

DROP TABLE TempOldTable;

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


26
ฉันจะไปหาตัวเลือกแรกและใช้ตัวเลือกเริ่มต้นออกจากตัวเลือกการเปลี่ยนแปลงตาราง {tableName} เพิ่มคอลัมน์ COLNew {type} DEFAULT {defaultValue}; สำคัญกว่า: (ลองคิดดูว่าทำไมคุณถึงต้องการเรียงลำดับคอลัมน์ .. ) ใช้ในทุก ๆ การบันทึก (เช่นการแทรกหรือเพิ่ม) ชื่อคอลัมน์ทุกครั้งด้วยวิธีนี้คุณจะไม่ได้รับข้อผิดพลาดเมื่อมีการเปลี่ยนแปลงตาราง
michel.iamit

5
โดยวิธีการ: ค่าเริ่มต้นไม่สามารถเพิ่มใน ALTER TABLE สำหรับบาง fieldtypes: sqlite.org/lang_altertable.html
michel.iamit

9
อย่าลืมสร้างดัชนีอีกครั้ง
Jan Turoň

5
คุณจะต้องสร้างทริกเกอร์ใหม่ด้วย
Christopher K.

7
อย่าลืมการละเมิดข้อ จำกัด ที่อาจเกิดขึ้นจากกุญแจต่างประเทศ: "... แต่อาจเรียกการกระทำที่เป็นกุญแจต่างประเทศหรือการละเมิดข้อ จำกัด " (ดูsqlite.org/foreignkeys.html#fk_schemacommands ); คุณสามารถปิดการใช้งานคีย์ต่างประเทศได้ในขณะเดียวกัน: PRAGMA foreign_keys = ON;(ดูsqlite.org/foreignkeys.html#fk_enable )
Trinimon

112

คุณไม่เพิ่มคอลัมน์ระหว่างคอลัมน์อื่น ๆ ใน SQL คุณเพียงแค่เพิ่มคอลัมน์ ที่ที่พวกเขาอยู่นั้นขึ้นอยู่กับ DBMS สถานที่ที่เหมาะสมเพื่อให้มั่นใจว่าคอลัมน์ออกมาในลำดับที่ถูกต้องคือเมื่อคุณselectให้พวกเขา

กล่าวอีกนัยหนึ่งถ้าคุณต้องการพวกเขาตามลำดับ{name,colnew,qty,rate}คุณใช้:

select name, colnew, qty, rate from ...

ด้วย SQLite คุณจำเป็นต้องใช้alter tableตัวอย่างเช่น:

alter table mytable add column colnew char(50)

2
SELECT * FROM mytable?
EML

การตั้งค่าเริ่มต้นคืออะไรหากเราไม่ได้ระบุไว้ในแถวที่มีอยู่ของคอลัมน์ใหม่
จาค็อบ

12
มีกรณีการใช้งานน้อยมากที่คุณควรทำselect *ทั้งหมด บางครั้งมันมีประโยชน์สำหรับโปรแกรมที่ต้องการค้นหาตาราง แต่สำหรับการใช้งานส่วนใหญ่คุณควรระบุสิ่งที่คุณต้องการอย่างชัดเจนและตามลำดับที่คุณต้องการ
paxdiablo

4
มันบ้าว่านี่ไม่ใช่ "คำตอบที่ยอมรับ" คำถามเดิมแสดงให้เห็นถึงการขาดความเข้าใจอย่างสมบูรณ์ว่า RDBMS ทำงานอย่างไร
Vada Poché

12

คุณสามารถเพิ่มคอลัมน์ใหม่ด้วยแบบสอบถาม

ALTER TABLE TableName ADD COLUMN COLNew CHAR(25)

แต่จะเพิ่มเมื่อสิ้นสุดไม่ใช่ในระหว่างคอลัมน์ที่มีอยู่


11

SQLite มีการสนับสนุน ALTER TABLE แบบ จำกัด ที่คุณสามารถใช้เพื่อเพิ่มคอลัมน์ไปยังจุดสิ้นสุดของตารางหรือเพื่อเปลี่ยนชื่อของตาราง

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

ตัวอย่างเช่นสมมติว่าคุณมีตารางชื่อ "t1" ที่มีชื่อคอลัมน์ "a" และ "c" และคุณต้องการแทรกคอลัมน์ "b" จากตารางนี้ ขั้นตอนต่อไปนี้อธิบายวิธีการทำสิ่งนี้:

BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,c);
INSERT INTO t1_backup SELECT a,c FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b, c);
INSERT INTO t1 SELECT a,c FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;

ตอนนี้คุณพร้อมที่จะแทรกข้อมูลใหม่ของคุณแล้ว:

UPDATE t1 SET b='blah' WHERE a='key'

ในการทดสอบของฉันบรรทัดINSERT INTO t1 SELECT a,c FROM t1_backup;ทำให้เกิดข้อผิดพลาด: "table t1 มี 3 คอลัมน์ แต่มีการระบุค่า 2 ค่า: INSERT INTO t1 SELECT a, c จาก t1_backup;" บรรทัดที่ถูกต้องควรเป็นINSERT INTO t1 (a,c) SELECT a,c FROM t1_backup;
JnLlnd

5
ALTER TABLE {tableName} ADD COLUMN COLNew {type};
UPDATE {tableName} SET COLNew = {base on {type} pass value here};

จำเป็นต้องมีการอัปเดตนี้เพื่อจัดการกับค่า Null โดยป้อนค่าเริ่มต้นตามที่คุณต้องการ ในกรณีของคุณคุณต้องโทรSELECTสอบถามและคุณจะได้รับคำสั่งของคอลัมน์ดังที่paxdiabloพูดไว้แล้ว:

SELECT name, colnew, qty, rate FROM{tablename}

และในความคิดของฉันชื่อคอลัมน์ของคุณเพื่อรับค่าจากเคอร์เซอร์:

private static final String ColNew="ColNew";
String val=cursor.getString(cursor.getColumnIndex(ColNew));

ดังนั้นหากดัชนีเปลี่ยนแปลงแอปพลิเคชันของคุณจะไม่ประสบปัญหาใด ๆ

นี่เป็นวิธีที่ปลอดภัยในแง่ที่มิฉะนั้นหากคุณกำลังใช้งานCREATE temptableหรือRENAME tableหรือCREATEอาจมีการสูญเสียข้อมูลสูงหากไม่ได้รับการจัดการอย่างรอบคอบตัวอย่างเช่นในกรณีที่ธุรกรรมของคุณเกิดขึ้นในขณะที่แบตเตอรี่หมด


4

ฉันกำลังเผชิญปัญหาเดียวกันและวิธีที่สองเสนอในคำตอบที่ยอมรับตามที่ระบุไว้ในความคิดเห็นอาจเป็นปัญหาเมื่อจัดการกับกุญแจต่างประเทศ

วิธีแก้ปัญหาของฉันคือการส่งออกฐานข้อมูลไปยังไฟล์ sql ตรวจสอบให้แน่ใจว่าคำสั่ง INSERT มีชื่อคอลัมน์ ฉันใช้DB Browser สำหรับ SQLiteซึ่งมีคุณสมบัติที่ใช้งานง่าย หลังจากนั้นคุณต้องแก้ไขคำสั่งสร้างตารางและแทรกคอลัมน์ใหม่ที่คุณต้องการและสร้าง db ใหม่

ใน * เหมือนระบบคืออะไรบางอย่างตามแนวของ

cat db.sql | sqlite3 database.db

ฉันไม่รู้ว่าสิ่งนี้เป็นไปได้อย่างไรกับฐานข้อมูลขนาดใหญ่มาก แต่มันใช้งานได้ในกรณีของฉัน

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