当我尝试使用Java将数据放入我的Oracle数据库时,我面临着我需要避免使用特殊字符或逃避它们的问题。 我敢肯定,有一种聪明的方法可以使用我不知道的功能来解决这个问题。
我的问题示例:
movie_name:加勒比海盗:死人的胸部
标题得到了#34; ' "这意味着,它将由Oracle数据库处理。使用Java变量将其置于INSERT语句中时,无法对其进行转义。
我想要进入我的数据库的数据来自电影数据库(TMDB),我使用名为themoviedbapi的包装器。使用该包装器,我自己编写了一个程序来获取数据并将其放入我的数据库中。
[...] for (int i = 0; i < tmdb_max_id; i++) {
int movie_count = 0;
try {
MovieDb movie_name = movies.getMovie(i, "en");
String imdb_id = movie_name.getImdbID();
db.processInsert("INSERT INTO TMDB_TEST_MOVIES (TMDB_ID, ORIGINAL_TITLE, IMDB_ID) "+
"VALUES ('"+i+"', '"+movie_name+"', '"+imdb_id+"')");
i++;
} catch (RuntimeException e) {
System.err.println("Error getting movie with ID " + i);
continue;
} catch (SQLException sqle) {
System.err.println(sqle+" SQL ERROR at movie with ID"+i);
throw sqle;
}[...]
我到达电影时看到的内容(见上文)如下:
Exception in thread "main" java.sql.SQLSyntaxErrorException: ORA-00917: Missing comma
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:227)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:195)
at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1036)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1336)
at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1916)
at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1878)
at oracle.jdbc.driver.OracleStatementWrapper.execute(OracleStatementWrapper.java:318)
at database.DatabaseConnect.processInsert(DatabaseConnect.java:24)
at tmdb_api_to_db.main.main(main.java:65)
这可能是因为我对非转义特殊字符有特定问题。一位同事告诉我,绑定变量有一种方法可以避免SQL注入,这也可以解决我的问题,但是 - 说实话 - 我搜索了这样的功能,并没有成功将其转移到我的特定问题
理想的解决方案是,如果有人可以告诉我如何构建我的INSERT语句以避免上述异常......
我完全乐于接受批评和建议!
正如您可能已经注意到的那样:我对SQL和Java的了解都很生气,所以请放纵:)
答案 0 :(得分:0)
只需在字符串中添加撇号即可。例如:
String movie_name = "Pirates of the Caribbean: Dead Man's Chest";
if (movie_name.contains("'")){
movie_name = movie_name.replaceAll("'", "''");
}
答案 1 :(得分:0)
以下是我如何解决它 - @Thomas和@Marmite轰炸机的信誉:)
我将PreparedStatement添加到我的DatabaseClass
package database;
import java.sql.*;
public class DatabaseConnect {
private Connection con;
public void connect(String user, String password, String dbUrl)
throws ClassNotFoundException, SQLException
{
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(dbUrl, user, password);
}
public void disconnect() throws SQLException
{
con.close();
}
public void processInsert(String sql) throws SQLException
{
Statement stmt = con.createStatement();
stmt.execute(sql);
stmt.close();
}
public ResultSet processQuery(String sql) throws SQLException
{
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
return rs;
}
public PreparedStatement prepareStatement(String sql) throws SQLException{
PreparedStatement ps = con.prepareStatement(sql);
return ps;
}
}
在我的Main中使用它像这样:
[...]PreparedStatement ps = db.prepareStatement("INSERT INTO TMDB_TEST_MOVIES
(TMDB_ID, ORIGINAL_TITLE, IMDB_ID) VALUES (?,?,?)");[...]
[...]for (int i = 0; i < tmdb_max_id; i++) {
try {
MovieDb movie_name = movies.getMovie(i, "en");
String original_title = movie_name.getOriginalTitle();
String imdb_id = movie_name.getImdbID();
ps.setInt(1,i);
ps.setString(2,original_title);
ps.setString(3,imdb_id);
ps.executeUpdate();
i++;
} catch (RuntimeException e) {
continue;
} catch (SQLException sqle) {
throw sqle;
}
}[...]
希望这可以在寻找问题时帮助某人... 干杯并再次感谢!