我有一个SQLite数据库,其中有一个表" Transactions"包含一个ID字段,它是一个主键并自动增加。
CREATE TABLE transactions (
id int AUTO_INCREMENT not null,
time DATETIME not null,
buyer varchar(320) not null,
seller varchar(320) not null,
price float not null,
size int not null,
currency char(3) not null,
symbol varchar(10) not null,
primary key (id)
);
我创建了一个Java类来处理SQL查询。
try {
PreparedStatement pStmt = db.getConnection().prepareStatement(
"INSERT INTO transactions( id, time, buyer, seller, price, size, currency, symbol ) " +
"VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )"
);
java.util.Date uDate = sdf.parse( curLine[0] );
try {
pStmt.setLong( 2, uDate.getTime() );
pStmt.setString( 3, curLine[1] );
pStmt.setString( 4, curLine[2] );
pStmt.setFloat( 5, Float.parseFloat( curLine[3] ) );
pStmt.setInt( 6, Integer.parseInt( curLine[4] ) );
pStmt.setString( 7, curLine[5] );
pStmt.setString( 8, curLine[6] );
pStmt.executeUpdate();
} catch( SQLException e ) {
e.printStackTrace();
}
} catch ( SQLException e ) {
e.printStackTrace();
}
curLine是从CSV文件解析的值数组。
在运行时,我有以下错误
org.sqlite.SQLiteException:[SQLITE_CONSTRAINT_NOTNULL] NOT NULL约束失败(NOT NULL约束失败:transactions.id)
我不知道如何处理它。
我尝试了其他几种配置:
但是这些配置中的每一个都会引发错误。
答案 0 :(得分:4)
从insert语句中删除id
,让sql有机会使用自己的进程自动增加:
"INSERT INTO transactions( time, buyer, seller, price, size, currency, symbol ) " +
"VALUES ( ?, ?, ?, ?, ?, ?, ? )"
编辑1
请使用符合SQLite的语法创建表:
sqlite> CREATE TABLE t2 ( id INTEGER PRIMARY KEY AUTOINCREMENT, size INTEGER NOT NULL);
sqlite> INSERT INTO t2 ( size) VALUES (123);
sqlite> INSERT INTO t2 ( size) VALUES (456);
sqlite> SELECT * FROM t2;
1|123
2|456
答案 1 :(得分:1)
@ bc004346答案是对的。我在这里添加一些细节。
这证明了你遇到的问题:
sqlite> create table a (id int AUTO_INCREMENT not null, v varchar(5));
sqlite> insert into a (v) values ('a');
Error: NOT NULL constraint failed: a.id
sqlite> drop table a;
sqlite> create table a (id integer PRIMARY KEY AUTOINCREMENT, v varchar(5));
sqlite> insert into a (v) values ('a');
sqlite> select * from a;
1|a
您遇到的问题是由sqlite中types work的方式引起的。类型与值本身无关,而与列无关。因为create table中的column这个typename的含义很少,甚至可以完全省略。
这是sqlite中的有效表定义:
create table a(x, y);
您可以将任何标记序列基本指定为类型名称:
sqlite> create table e (id int xxxx xxx not null, v varchar(5));
sqlite> create table f (id int xxxx xxx yyyy not null, v varchar(5));
sqlite> create table g (id inteeeee xxxx xxx yyyy not null, v varchar(5));
sqlite> create table h (id what ever you want not null, v varchar(5));
考虑到这一点,您可以看到为表transactions
指定的定义无法按预期方式工作,即列ID不是自动增量列,并被视为具有not null
约束的常规列。如果没有在insert语句中为其指定值,则会出现约束违规。
要解决此问题,您需要使用正确的语法来创建AUTOINCREMENT
字段或手动生成id列值并在插入期间设置它。