一种不使用Java for Oracle-Insert转义特殊字符的方法吗?

时间:2017-01-30 17:02:01

标签: java sql oracle themoviedb-api

当我尝试使用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的了解都很生气,所以请放纵:)

2 个答案:

答案 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;
            }

        }[...]

希望这可以在寻找问题时帮助某人... 干杯并再次感谢!