【问题标题】:A not null constraints failed非空约束失败
【发布时间】:2019-09-05 08:11:08
【问题描述】:

org.sqlite.SQLiteException: [SQLITE_CONSTRAINT_NOTNULL] A NOT NULL 约束失败(NOT NULL 约束失败:stock.id)

我的 SQLite 数据库中有三列 idpnamemrp,但我只想将数据插入两列, 然后我做了这个

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 
    try {
        Class.forName("org.sqlite.JDBC");
        Connection con = DriverManager.getConnection("jdbc:sqlite:qmb.db");
        String query="INSERT INTO stock(pname,mrp) VALUES('"+jTextField2.getText()+"','"+jTextField5.getText()+"');";
        executeSQlQuery(query, "Inserted");   // TODO add your handling code here:
    } catch (ClassNotFoundException | SQLException ex) {
        Logger.getLogger(UpdateStock.class.getName()).log(Level.SEVERE, null, ex);
    }
}    

我只是希望能够通过单击一个按钮将行插入到数据库中

【问题讨论】:

  • 了解 sql 表中的非空约束。这会让你对这个问题有所了解。
  • 显示你的表定义。
  • 还阅读了如何将值绑定到 sql 语句中的参数,而不是尝试直接在其中使用用户提供的字符串构建语句。不要对 sql 注入敞开心扉。
  • 您的表的“id”列似乎有一个约束,说明此列中没有条目可以有“null”值。我的猜测是您的表未配置为为新条目自动生成“id”。要解决这个问题,您可以在输入新条目时提供一个 id(不推荐),或者让您的数据库为您生成它。
  • id 很可能是 PRIMARY KEY 但没有自动增量标志。 PK 根据定义不可为空。您要么更改 DDL 以将此列与自动序列一起放置,要么提供值。 PS,请检查如何在java中防止SQL InjectionJTextField 值的串联真的很糟糕

标签: java sql sqlite


【解决方案1】:

在 SQLite 中创建表时,您要用作主键的列(在本例中为 id)必须使用确切关键字 INTEGER PRIMARY KEY行为成为 SQLite 的自动增量的轻量级版本。这就是允许您在不提供列值的情况下添加行的原因(SQLite 会为您填写)。 INT PRIMARY KEY 不会这样做,UNSIGNED INTEGER PRIMARY KEY 也不会这样做,任何其他变体也不会。尝试使用INTEGER PRIMARY KEY 作为id 的类型重新创建表(您也可以添加NOT NULL 约束)。

您可以选择将关键字AUTOINCREMENT 添加到id 的定义中(即使用INTEGER PRIMARY KEY AUTOINCREMENT)。这将强制 SQLite 在添加新行时不重用以前删除的行的 ID,但这会更慢并且占用更多的内存和磁盘空间。

下面是一个示例,说明如何在 SQLite 中创建表,这样插入行时就不必填写id

CREATE TABLE stock(id INTEGER PRIMARY KEY, pname TEXT, mrp TEXT);

附: - 由于INTEGER PRIMARY KEY 的这一特殊功能通过创建从idROWID 的别名来工作,因此在创建表时不应同时使用WITHOUT ROWID 关键字。

附言- 您没有关闭您在上面的代码中创建的 SQL 连接(我忽略了其他主要问题,但这是最重要的)。您需要在 finally 子句中执行此操作,以确保即使发生异常也关闭连接:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 
    Connection con = null;
    try {
        Class.forName("org.sqlite.JDBC");
        con = DriverManager.getConnection("jdbc:sqlite:qmb.db");
        String query="INSERT INTO stock(pname,mrp) VALUES('"+jTextField2.getText()+"','"+jTextField5.getText()+"');";
        executeSQlQuery(query, "Inserted");   // TODO add your handling code here:
    } catch (ClassNotFoundException | SQLException ex) {
        Logger.getLogger(UpdateStock.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        if (con != null) {
            try {
                con.close();
            } catch (SQLException ex) {
                Logger.getLogger(UpdateStock.class.getName()).log(Level.WARNING, "can't close SQL connection!" , ex);
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    在创建表时,您必须将 id 作为主键。所以,id 不能为空。首先将您的 id 列设置为自动递增。 这仅在您使用 db 查询插入记录时才有效。如果您尝试在 db 中手动插入记录,则必须手动在 id 列中指定值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-17
      • 2018-11-17
      相关资源
      最近更新 更多