java - 尝试将行插入表时出现 SQL 语法错误异常

标签 java sql intellij-idea derby

您好,我在执行以下功能时遇到了问题,但没有遇到以下异常。我不确定为什么会这样。我认为这可能与引号有关。如果重要的话,我正在使用 derby 数据库。

java.sql.SQLSyntaxErrorException

这是我正在尝试执行的以下代码:

public void addAlbum(Album album) throws IOException, SQLException {
    Properties props = new Properties();
    FileInputStream in = new FileInputStream("database.properties");
    props.load(in);
    in.close();

    props.getProperty("jdbc.drivers");
    String url = props.getProperty("jdbc.url");
    String username = props.getProperty("jdbc.username");
    String password = props.getProperty("jdbc.password");

    Connection connection = DriverManager.getConnection(url, username, password);
    Statement statement = connection.createStatement();
    String sql = null;

    if(album instanceof CDAlbum) {
        CDAlbum cdAlbum = (CDAlbum)album;
        sql = "INSERT INTO MyAlbums VALUES ('CD', '" + cdAlbum.getTitle() + "', '" + cdAlbum.getGenre() + "','" + cdAlbum.getArtist() + "', '" + cdAlbum.getTracks() + "');";
    }
    if(album instanceof DVDAlbum) {
        DVDAlbum dvdAlbum = (DVDAlbum)album;
        sql = "INSERT INTO MyAlbums VALUES ('DVD', '" + dvdAlbum.getTitle() + "', '" + dvdAlbum.getGenre() + "','" + dvdAlbum.getDirector() + "', '" + dvdAlbum.getPlotOutline() + "');";
    }

    statement.executeUpdate(sql);
    System.out.println("Album Added!");

    if(statement != null) {
        statement.close();
    }
    if(connection != null) {
        connection.close();
    }
}

这是个异常(exception):

java.sql.SQLSyntaxErrorException: Syntax error: Encountered "t" at line 2, column 5.
at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedStatement.executeLargeUpdate(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedStatement.executeUpdate(Unknown Source)
at au.edu.uow.CollectionDB.MyCollectionDB.addAlbum(MyCollectionDB.java:194)
at au.edu.uow.Collection.CollectionFactory.loadCollection(CollectionFactory.java:136)
at MyCollection.main(MyCollection.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: ERROR 42X01: Syntax error: Encountered "t" at line 2, column 5.
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
at org.apache.derby.impl.sql.compile.ParserImpl.parseStatementOrSearchCondition(Unknown Source)
at org.apache.derby.impl.sql.compile.ParserImpl.parseStatement(Unknown Source)
at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source)
... 11 more

最佳答案

XKCD SQL injection XKCD #327 (http://xkcd.com/327/)

使用PreparedStatement!

我可以建议:

try (final PreparedStatement preparedStatement = con.prepareStatement(sql)) {
    if (album instanceof CDAlbum) {
        CDAlbum cdAlbum = (CDAlbum) album;
        preparedStatement.setString(1, "CD");
        preparedStatement.setString(2, cdAlbum.getTitle());
        preparedStatement.setString(3, cdAlbum.getGenre());
        preparedStatement.setString(4, cdAlbum.getArtist());
        preparedStatement.setString(5, cdAlbum.getTracks());
    } else if (album instanceof DVDAlbum) {
        DVDAlbum dvdAlbum = (DVDAlbum) album;
        preparedStatement.setString(1, "DVD");
        preparedStatement.setString(2, dvdAlbum.getTitle());
        preparedStatement.setString(3, dvdAlbum.getGenre());
        preparedStatement.setString(4, dvdAlbum.getDirector());
        preparedStatement.setString(5, dvdAlbum.getPlotOutline());
    }
    dvdAlbum.getPlotOutline();
}

这可以防止数据中出现任何可能导致查询失败的奇怪值。另请注意,我使用 try-with-resources 构造,这将始终关闭资源。如果查询中出现错误,您当前的代码存在内存泄漏 - 将引发异常并跳过 close() 调用。你在很多地方都有这个问题,当你阅读文件时,当你打开连接时,等等......

我还将您的 if...if 更改为 if...else if 因为我认为 CDAlbum 不太可能也将是一个 DVDAlbum。命名说明 - 类名中的首字母缩写词最好用单词表示 - DvdAlbum 而不是 DVDAlbum

此外,我建议您了解方法重载和多态性。在代码中使用 if instanceof 是代码异味的明确标志。

尽管将完全不同的数据存储在同一张表中的整个想法是设计问题的明确标志。此外,像 tracks 这样的字段 - 肯定需要另一个表吗?!

关于java - 尝试将行插入表时出现 SQL 语法错误异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25811597/

相关文章:

java - 如何阻止 IntelliJ 将参数放在自己的行上?

java - 具有自定义对象的可编辑组合框重写下拉列表中的项目

java - java中lastIndexOf的时间复杂度是多少?

java - 使用javah生成头文件

java - boolean 值在线程中不改变

sql - MySQL:查询根据另一列的属性对数据进行排序

intellij-idea - Kotlin - 提取变量快捷方式后在 IntelliJ 中明确指定类型

mysql - 大量非常简单的sql查询会影响性能吗?

mysql查询: i want to 2 queries result merged w. r.t主键

java - java中没有合适的驱动程序发现错误?