【问题标题】:Insert Statement into Derby Database将语句插入 Derby 数据库
【发布时间】:2019-10-13 09:27:12
【问题描述】:

我试图在我的 java derby 数据库中的表中插入一些值,我收到错误 java.sql.SQLSyntaxErrorException: VALUES 子句必须包含至少一个元素。不允许使用空元素。

    public boolean registerStudent(Student student)
    {
        try
        {
        Connection conn = DriverManager.getConnection("jdbc:derby://localhost:1527/AceDrivingSchool", "ADC", "ADC");
        Statement stmt = conn.createStatement();
        stmt.executeUpdate("INSERT INTO ADC.STUDENT(EMAILADDRESS, FORENAME, SURNAME, ADDRESSLINE1, ADDRESSLINE2,"
                + " POSTCODE, TELEPHONENO, GENDER, PASSWORD, ISREGISTERED, ISVERIFIED, PASSEDTHEORY, PASSEDPRACTICAL, DRIVINGLICENSENO, DOB"
                + ") VALUES('" + student.getEmailAddress() +
                "', '" + student.getForename() + "', '" + student.getSurname() + 
                "', '" + student.getAddressLine1() + "', '" + student.getAddressLine2() + "', '" + student.getPostcode() + 
                "', '" + student.getTelephoneNo() + "', '" + student.getGender() + "', '" + student.getPassword() + 
                "', '" + student.isIsRegistered() + "', '" + student.isIsVerified() + "', '" + student.isPassedTheory() + "', '" +
                "', '" + student.isPassedPractical() + "', '" + student.getdrivingLicenseNo() + "', '" + 
                new SimpleDateFormat("yyyy-MM-dd").format(student.getDob()) + "')");   
        conn.close();
        return true;
        }
        catch(SQLException ex)
        {
            ex.printStackTrace();
            return false;
        }
    }

这应该将值正确地放到我的表中

【问题讨论】:

  • 您正在动态构建一个字符串以作为 SQL 代码执行。然后数据库返回错误。您的第一步应该是检查该字符串并查看它实际上是什么。您正在执行的 SQL 代码很有可能不是您假设正在执行的 SQL 代码。
  • 我意识到我有一个额外的“','”,虽然我现在收到一个新错误“java.sql.SQLSyntaxErrorException:分配的值的数量与指定的数量不同或隐含列。”我是这些错误的新手/以前从未遇到过。
  • 那个错误告诉你列数和值的个数不一样。数一数。
  • 您的代码易受 SQL 注入攻击。使用“准备好的语句”而不是普通的 SQL。
  • 顺便说一下,使用LocalDate.parse而不是SimpleDateFormat

标签: java sql database derby


【解决方案1】:

@Basil 给出的答案是完全正确的,您必须阅读并理解它才能了解如何构建和执行查询的基本概念。

不过,在您的情况下,我可以在 cmets 中看到您面临的 java.sql.SQLSyntaxErrorException: The number of values assigned is not the same as the number of specified or implied columns. 这背后的原因是您的格式错误的 SQL 有额外的 ","

删除"+,以及其他sql格式你会得到这个,

INSERT INTO adc.student 
            ( 
                        emailaddress, 
                        forename, 
                        surname, 
                        addressline1, 
                        addressline2, 
                        postcode, 
                        telephoneno, 
                        gender, 
                        password, 
                        isregistered, 
                        isverified, 
                        passedtheory, 
                        passedpractical, 
                        drivinglicenseno, 
                        dob 
            ) 
            VALUES 
            ( 
                        student.Getemailaddress() , 
                        student.Getforename() , 
                        student.Getsurname() , 
                        student.Getaddressline1() , 
                        student.Getaddressline2() , 
                        student.Getpostcode() , 
                        student.Gettelephoneno() , 
                        student.Getgender() , 
                        student.Getpassword() , 
                        student.Isisregistered() , 
                        student.Isisverified() , 
                        student.Ispassedtheory() , 
                        , 
                        student.ispassedpractical() , 
                        student.getdrivinglicenseno() , 
                        NEW simpledateformat(yyyy-mm-dd).format(student.getdob()) 
            )

SQL 解析在第 33 行失败。删除student.isPassedTheory() 之后的附加+ "', '",您将能够执行查询。 您应该在修复代码后得到以下查询格式,

"INSERT INTO ADC.STUDENT(EMAILADDRESS, FORENAME, SURNAME, ADDRESSLINE1, ADDRESSLINE2,"
                + " POSTCODE, TELEPHONENO, GENDER, PASSWORD, ISREGISTERED, ISVERIFIED, PASSEDTHEORY, PASSEDPRACTICAL, DRIVINGLICENSENO, DOB"
                + ") VALUES('" + student.getEmailAddress() +
                "', '" + student.getForename() + "', '" + student.getSurname() + 
                "', '" + student.getAddressLine1() + "', '" + student.getAddressLine2() + "', '" + student.getPostcode() + 
                "', '" + student.getTelephoneNo() + "', '" + student.getGender() + "', '" + student.getPassword() + 
                "', '" + student.isIsRegistered() + "', '" + student.isIsVerified() + "', '" + student.isPassedTheory() +
                "', '" + student.isPassedPractical() + "', '" + student.getdrivingLicenseNo() + "', '" + 
                new SimpleDateFormat("yyyy-MM-dd").format(student.getDob()) + "')");   

【讨论】:

    【解决方案2】:

    Desai 的correct Answer 在生成的 SQL 语句中发现了您的语法错误:逗号错误。

    这是编写 SQL 的更好方法,您可以自己发现此类错误。

    您应该始终将 SQL 单独构建为一段文本,以方便调试此类问题。

    构建您的 SQL 文本并检查

    使用StringBuilder 构建文本。

    这里是示例代码。你用你的对象getter方法填写xxx(我太懒了)。

    StringBuilder sql = new StringBuilder() ;
    String eol = "\n" ;  // linefeed
    String comma = " , " ;  // SPACE + COMMA + SPACE
    sql.append( "INSERT INTO ADC.STUDENT ( " ).append( eol ) ;
    sql.append( "    EMAILADDRESS, FORENAME, SURNAME, ADDRESSLINE1, ADDRESSLINE2, POSTCODE, TELEPHONENO, GENDER, PASSWORD, ISREGISTERED, ISVERIFIED, PASSEDTHEORY, PASSEDPRACTICAL, DRIVINGLICENSENO, DOB " ).append( eol) ;
    sql.append( ") VALUES (" ).append(eol) ;
    sql.append( student.getEmailAddress() ).append( comma ) ; // EMAILADDRESS
    sql.append( student.getForename()  ).append( comma ) ; // FORENAME
    sql.append( xxx ).append( comma ) ; // SURNAME
    sql.append( xxx ).append( comma ) ; // ADDRESSLINE1
    sql.append( xxx ).append( comma ) ; // ADDRESSLINE2
    sql.append( xxx ).append( comma ) ; // POSTCODE
    sql.append( xxx ).append( comma ) ; // TELEPHONENO
    sql.append( xxx ).append( comma ) ; // GENDER
    sql.append( xxx ).append( comma ) ; // PASSWORD
    sql.append( xxx ).append( comma ) ; // ISREGISTERED
    sql.append( xxx ).append( comma ) ; // ISVERIFIED
    sql.append( xxx ).append( comma ) ; // PASSEDTHEORY
    sql.append( xxx ).append( comma ) ; // PASSEDPRACTICAL
    sql.append( xxx ).append( comma ) ; // DRIVINGLICENSENO
    sql.append( xxx ) ; // DOB — IMPORTANT no comma on the last item. 
    sql.append( ") ;" ) ;
    

    然后打印出该值以验证您的 SQL 是否正确。比较 other examples of SQL 来发现你的嘘声。

    我们将礼貌地忽略不加盐和散列的密码、许可证号和出生日期作为重大安全风险的保存。

    顺便说一句,您应该将 Java 对象上的仅日期值(例如出生日期)表示为 LocalDate 对象。可怕的 DateSimpleDateFormat 类在几年前被 java.time 类所取代。 LocalDate.toString() 方法生成标准 ISO 8601 格式的文本,这恰好与 SQL 中常用的相同。

    准备好的声明

    比上面更好的方法是使用带有占位符的准备好的语句。像你一样执行生成的文本阅读起来更复杂,更重要的是,会让你面临SQL Injection 攻击的风险。

    StringBuilder sql = new StringBuilder() ;
    String eol = "\n" ;  // linefeed
    sql.append( "INSERT INTO ADC.STUDENT ( " ).append( eol ) ;
    sql.append( "    EMAILADDRESS, FORENAME, SURNAME, ADDRESSLINE1, ADDRESSLINE2, POSTCODE, TELEPHONENO, GENDER, PASSWORD, ISREGISTERED, ISVERIFIED, PASSEDTHEORY, PASSEDPRACTICAL, DRIVINGLICENSENO, DOB " ).append( eol) ;
    sql.append( ") VALUES (" ).append(eol) ;
    sql.append( "? , " ) ; // EMAILADDRESS
    sql.append( "? , " ) ; // FORENAME
    sql.append( "? , " ) ; // SURNAME
    sql.append( "? , " ) ; // ADDRESSLINE1
    sql.append( "? , " ) ; // ADDRESSLINE2
    sql.append( "? , " ) ; // POSTCODE
    sql.append( "? , " ) ; // TELEPHONENO
    sql.append( "? , " ) ; // GENDER
    sql.append( "? , " ) ; // PASSWORD
    sql.append( "? , " ) ; // ISREGISTERED
    sql.append( "? , " ) ; // ISVERIFIED
    sql.append( "? , " ) ; // PASSEDTHEORY
    sql.append( "? , " ) ; // PASSEDPRACTICAL
    sql.append( "? , " ) ; // DRIVINGLICENSENO
    sql.append( "? " ) ;   // DOB — IMPORTANT no comma on the last item. 
    sql.append( ") ; " ) ;
    

    再次打印出来并检查。

    String sqlOutput = sql.toString() ;
    System.out.println( sqlOutput ) ;
    

    创建一个PreparedStatement。在该对象上调用 set… 方法。

    ps.setString( 1 , student.getEmailAddress() ) ;
    …
    ps.setObject( 15 , student.getDateOfBirth() ) ;  // Pass `LocalDate` object via `setObject` method using JDBC 4.2 or later.
    

    【讨论】:

      【解决方案3】:

      请注意,当您将杂散语法放入 SQL 语句时也会发生这种情况,例如:

      INSERT INTO table ( a, b, c ) VALUES = ( 1, 2, 3 )
      

      虽然报告的错误与原始问题相同,但它不是错误的列和提供的值甚至缺少逗号,而是您盲目输入的等号。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多