【问题标题】:Satisfying SQLite constraint with Java JDBC queries使用 Java JDBC 查询满足 SQLite 约束
【发布时间】:2017-03-02 17:18:56
【问题描述】:

我有一个 SQLite 数据库,其中“事务”表包含一个 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)

我不知道如何处理它。

我尝试了其他几种配置:

  • 不要在sql查询中指明“id”字段。
  • 为“id”赋予 0 值。

但是这些配置中的每一个都会引发错误。

【问题讨论】:

  • 非常不言自明,您将null 传递给不接受null 的列的参数(当前,任何列)。如果不显示更多代码,很难说是哪个,但总体而言,数组很可能在没有设置特定索引的情况下被初始化(因此默认为 null)。这是您调试代码的地方(添加打印语句并查看正在传递的当前值)。
  • 但我不想将任何值传递给id,因为它是一个自动增量字段。所以我希望它表现得像一个正常的自动增量字段。
  • 您是自己执行 CREATE TABLE 语句,还是应该是已经存在的 SQLite 表的 DDL?
  • @GordThompson 该表是在终端进程中单独创建的。

标签: java sqlite jdbc


【解决方案1】:

从插入语句中删除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

【讨论】:

  • 它不起作用。我有以下错误[SQLITE_CONSTRAINT_NOTNULL] A NOT NULL constraint failed (NOT NULL constraint failed: transactions.id) 我试图从 SQL 架构中删除非空约束,但它会导致一个空字段(不会发生自动增量)
  • 嗯...你确定你使用 SQLLite 吗?因为语法是 SQLLite 是column1 INTEGER AUTOINCREMENT,而不是id int AUTO_INCREMENT not null,
  • 另外你为什么没有PRIMARY KEY
  • @PierreP。不要遗漏第一个 Prepared Statement 值 pStmt.setLong( 1。比这个解决方案应该有效。对于自动递增值,有两种方法。将它们设置为不同的值或将它们完全留在插入中。
  • 是的,它是AUTOINCREMENT 你使用的是什么版本?它是 SQLLite 的一些自定义风格吗?
【解决方案2】:

@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 约束的常规列。如果您没有在插入语句中为其指定值,则会违反约束。

要克服这个问题,您要么需要使用正确的语法来创建 AUTOINCREMENT 字段,要么手动生成 id 列值并在插入期间设置它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 2012-05-16
    • 2015-08-24
    相关资源
    最近更新 更多