【问题标题】:JDBC SQLite not enforcing unique primary key constraintJDBC SQLite 不强制唯一主键约束
【发布时间】:2014-11-28 05:38:44
【问题描述】:

谁能告诉我为什么我的 SQLite JDBC 数据库没有强制执行唯一主键约束?

建表方法是:

public static void TableCars()
      {
        Connection c = null;
        Statement stmt = null;
        try {
          Class.forName("org.sqlite.JDBC");
          c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db");
          System.out.println("Opened database successfully");

          stmt = c.createStatement();
          String sql = "CREATE TABLE IF NOT EXISTS CARS3 " +
                       "(REGISTRATION TEXT PRIMRY KEY   NOT NULL, " + 
                       " PHONE               TEXT       NOT NULL," +
                       " MAKE                TEXT       NOT NULL, " + 
                       " MODEL               TEXT, " + 
                       " COLOUR              TEXT)";
          stmt.executeUpdate(sql);
          stmt.close();
          c.close();
        } catch ( Exception e ) {
          System.err.println( e.getClass().getName() + ": " + e.getMessage() );
          System.exit(0);
        }
        System.out.println("Cars3 created successfully");
      }

插入方法是:

 public static void InsertCars(String table, String phone, String registration, String make, String model, String colour)
  {
    Connection c = null;
    PreparedStatement pstmt = null;
    try {
      Class.forName("org.sqlite.JDBC");
      c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db");
      c.setAutoCommit(false);
      System.out.println("Opened database successfully");

      String query="INSERT INTO "+table+" (PHONE,REGISTRATION,MAKE, MODEL,COLOUR) VALUES (?,?,?,?,?)";

      pstmt = c.prepareStatement(query);

      pstmt = c.prepareStatement
              ("insert into CARS3 values(?,?,?,?,?)");
        pstmt.setString(1,registration);
        pstmt.setString(2,phone);
        pstmt.setString(3, make);
        pstmt.setString(4, model);
        pstmt.setString(5, colour);         
        pstmt.executeUpdate();

        pstmt.close();
      c.commit();
      c.close();
    } catch ( Exception e ) {
      System.err.println( e.getClass().getName() + ": " + e.getMessage() );
      System.exit(0);
    }
    System.out.println("Car Records created successfully");
  }

而不应该被允许,但可以重复执行的代码行是:

DbHandler.InsertCars("Cars3", "1","BN51 MZY", "Mini", "C220", "BLACK");

【问题讨论】:

  • 你是说这个InsertCars方法没有打印出错误信息?
  • 如前所述...您的查询有'PRIMRY KEY'

标签: java eclipse sqlite jdbc primary-key


【解决方案1】:

您的创建 SQL 声明 PRIMRY KEY 而不是 PRIMARY KEY。因此,您的表最初是在没有 PRIMARY KEY 约束的情况下创建的,并且由于您添加了 'IF NOT EXISTS' 条件,因此在之前删除该表之前,新的创建不会唤醒效果。

您的表在没有PRIMARY KEY 约束的情况下创建的原因可以在column-constraint 图表中找到:

约束定义错误(PRMARY 不是PRIMARY),(红色标注)导致列约束子语法没有被触发。

【讨论】:

  • 这是因为 SQLite 允许几乎任何东西作为声明的列类型,因此 PRIMRY KEY 成为该列的数据类型...
  • @MarkRotteveel 不是错误,而是功能。如果你仔细检查sqlite.org/lang_createtable.html 的语法图,你会注意到一个类型名可以由任意数量的部分组成,在这种情况下,它只有在遇到“NOT NULL”时才会进入列约束部分。跨度>
  • 这是语法错误,意味着它没有注册主键。现在我已经更正了它并制作了一个新版本的表,如果我尝试复制主键,它会给出错误 [SQLITE_CONSTRAINT] Abort due to constraint violation (UNIQUE constraint failed: CARS4.REGISTRATION)
  • @PabloFranciscoPérezHidalgo 令牌 PRMARYKEY 不会触发 column-constraint 语法并被 type-name 中的 name 循环消耗。 IF NOT EXISTS 通常是代码异味,但不是根本原因。
猜你喜欢
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多