2012-07-15 32 views
20

Trong sqlite3 faq, nó được đề cập rằng một khóa nguyên nguyên đang được nạp một giá trị null sẽ tự động. Nhưng điều này không xảy ra với tôi.Không có autoincrement cho khóa chính Integer trong sqlite3

để tái tạo, một bảng trong sqlite3, CREATE TABLE dummy(serial_num INTEGER PRIMARY KEY, name TEXT); và điền nó sử dụng python,

import sqlite3 as lite 
con = lite.connect('some.db') 
cur=con.cursor() 
data = "someone's name" 
cur.execute("INSERT INTO dummy VALUES(NULL, ?)", data) 
con.commit() 

Các serial_num thuộc tính đầu tiên đang được hiển thị trống trong khi các thuộc tính tên là tốt. Khi tôi làm SELECT serial_num FROM dummy Tôi chỉ nhận được một loạt các khoảng trống. Tôi đang làm gì sai?

+0

Tôi phải thêm, rằng tôi đã thử xác định lược đồ là '... serial_num INTEGER PRIMARY KEY NOT NULL ...' và nhận được lỗi 'sqlite3.IntegrityError: dummy.serial_no có thể không là NULL' – yayu

Trả lời

25

Đây là một trong những quirks của SQLite. Từ fine manual:

According to the SQL standard, PRIMARY KEY should always imply NOT NULL. Unfortunately, due to a long-standing coding oversight, this is not the case in SQLite. Unless the column is an INTEGER PRIMARY KEY SQLite allows NULL values in a PRIMARY KEY column. We could change SQLite to conform to the standard (and we might do so in the future), but by the time the oversight was discovered, SQLite was in such wide use that we feared breaking legacy code if we fixed the problem.

Các tài liệu trên INTEGER PRIMARY KEY là một chút không rõ ràng về những gì chính xác là cần thiết cho một cột được này INTEGER đặc biệt PRIMARY KEY rằng tính năng tự động gia tăng nhưng thực tế là cột cần phải được NOT NULL nếu bạn muốn sử dụng các giá trị NULL có nghĩa là "cho tôi giá trị auto-incrementing tiếp theo" khi chèn:

create table dummy (
    serial_num integer primary key not null, 
    name text 
); 

Nếu bạn bỏ qua các not null, bạn cần phải làm chèn của bạn như thế này:

insert into dummy (name) values (?) 

để nhận giá trị gia tăng tự động cho serial_num. Nếu không, SQLite không có cách nào để nói sự khác biệt giữa một NULL có nghĩa là "cho tôi giá trị gia tăng tự động tiếp theo" và một ý nghĩa NULL "đặt một giá trị NULL trong serial_num vì cột cho phép NULL".

+1

Cảm ơn rất nhiều. Trong khi thử nghiệm, tôi cũng học được rằng autoincrement chỉ hoạt động với một cột làm khóa chính. – yayu

+0

@yayu: Phần đó của [tài liệu] (http://www.sqlite.org/lang_createtable.html#primkeyconst) khá rõ ràng ít nhất: "Nếu bảng có một khóa chính cột đơn và loại được khai báo là cột đó là 'INTEGER' ..." –

2

Cú pháp chèn được cung cấp ở trên dường như không hoạt động khi không có not null.

Đây là một ví dụ - lưu ý rằng trường ID không được tự động tăng lên ngay cả khi tôi sử dụng định dạng chèn mà bạn đã chỉ định ở trên.

sqlite> .schema logTable 
CREATE TABLE logTable (ID INTEGER PRIMARY_KEY, ts REAL, level TEXT, message TEXT); 
sqlite> INSERT into LOGTABLE (ts, level, message) VALUES (111, "autoinc test", "autoinc test"); 
sqlite> select * from logtable where ts = 111; 
|111.0|autoinc test|autoinc test 
sqlite> 

Nó hoạt động với giải pháp NOT NULL.

sqlite> create TABLE logTable (ID INTEGER PRIMARY KEY NOT NULL, ts REAL, level TEXT, message TEXT); 
sqlite> INSERT into LOGTABLE (ts, level, message) VALUES (222, "autoinc test", "autoinc test"); 
sqlite> select * from logtable where ts = 222; 
1|222.0|autoinc test|autoinc test 

Tôi xin lỗi vì đã gửi bài này như một câu trả lời mới thay vì bình luận về các câu trả lời trước, nhưng điểm danh tiếng của tôi là quá thấp để thêm ý kiến, và tôi nghĩ rằng điều quan trọng là cần lưu ý rằng tuyên bố thay thế chèn là không phải là giải pháp thích hợp.

Các vấn đề liên quan