简体   繁体   中英

Satisfying SQLite constraint with Java JDBC queries

I have a SQLite database where a table "Transactions" contains an ID field which is a primary key and is autoincremented.

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)
);

I have created a Java class to handle SQL queries.

            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 is an array of values parsed from a CSV file.

At runtime, I have the following error

org.sqlite.SQLiteException: [SQLITE_CONSTRAINT_NOTNULL] A NOT NULL constraint failed (NOT NULL constraint failed: transactions.id)

I don't know how to handle it.

I have tried several other configurations:

  • Don't indicate the "id" field in the sql query.
  • Give a 0 value to "id".

But each of these configurations raise an error.

Remove the id from your insert statement to give sql a chance to use its own process to auto-increment:

"INSERT INTO transactions( time, buyer, seller, price, size, currency, symbol ) " +
                            "VALUES ( ?, ?, ?, ?, ?, ?, ? )"

EDIT 1

Please use SQLite compliant syntax for your table creation:

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

@bc004346 answer is correct. I'll add some details here.

This demonstrates the problem you have:

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

The problem you face is caused by the way types work in sqlite. Type is associated with value itself not with a column. As a consequence of this typename for column in create table has very little meaning and even can be omitted completely.

This is a valid table definition in sqlite:

create table a(x, y);

You can specify basically any sequence of tokens as a type name:

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));

Having this in mind you can see that the definition you specified for table transactions does not work the way you expect, namely column id is not autoincrement column and is treated as regular column with not null constraint . If you do not specify a value in insert statement for it you get constraint violation.

To overcome this you either need to use correct syntax to create AUTOINCREMENT field or manually generate id column value and set it during insert.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM