您好,我在执行以下功能时遇到了问题,但没有遇到以下异常。我不确定为什么会这样。我认为这可能与引号有关。如果重要的话,我正在使用 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 #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/