【问题标题】:ORA-00917: missing comma - Insert query failedORA-00917: 缺少逗号 - 插入查询失败
【发布时间】:2016-02-07 12:28:05
【问题描述】:

我正在尝试在 JSP 页面中创建插入查询,如下所示

    try 
    {
        Class.forName("oracle.jdbc.driver.OracleDriver");
    } 
    catch (ClassNotFoundException e) 
    {
        e.printStackTrace();
    }

    try 
    {
        connection = DriverManager.getConnection(
        "jdbc:oracle:thin:@localhost:1521:" + "XE", "hr","hr");

        if (connection != null) 
        {
            statement = connection.createStatement();

            String q2 = "INSERT INTO HR.tweets (";
            q2 = q2 + "DATE_TIME,USER_NAME,TWEET_BEFORE,TWEET_AFTER)";
            q2 = q2 + "VALUES (";
            q2 = q2 + "(select SYSDATE from dual),";
            q2 = q2 + "'" + tweet.getUser().getScreenName() + "'" + ",";
            q2 = q2 + "'" + tweet.getText() + "'" +",";
            q2 = q2 + "'" + finalstring + "')";

            statement.execute(q2);   
            statement.close();
            connection.close();
        }
    } 
    catch (SQLException e) 
    {
    e.printStackTrace();
    } 

statement.execute(q2) 我收到ORA-00917: missing comma error

以下查询是在代码中创建的:

INSERT INTO HR.tweets (DATE_TIME,USER_NAME,TWEET_BEFORE,TWEET_AFTER)VALUES ((select SYSDATE from dual),'Dannazxcv','RT @HugotInhinyero: Wish we could turn back time to the good old days. When our mama sings us to sleep but now we're stressed out.????????
#engin…','hugotinhinyero turn back time good days. mama sing sleep we're stress out.   engin'  )

请帮助我。

【问题讨论】:

  • 以下查询是在代码中创建的:INSERT INTO HR.tweets (DATE_TIME,USER_NAME,TWEET_BEFORE,TWEET_AFTER)VALUES ((select SYSDATE from dual),'Dannazxcv','RT @HugotInhinyero: Wish我们可以让时光倒流到过去的美好时光'压力很大。引擎')
  • 将这两行改为q2 = q2 + "SELECT"; q2 = q2 + "SYSDATE,";,并在末尾添加一个 FROM DUAL 参数
  • 首先不需要select。只需在 values 子句中使用sysdate。但你应该真的使用PreparedStatement

标签: java sql oracle jsp jdbc


【解决方案1】:

您的 SQL 插入有语法错误,因为您的参数之一包含 ':

'hugotinhinyero turn back time good days. mama sing sleep we're stress out. engin'

为避免此类错误,请勿手动构建 SQL 字符串,而是使用 PreparedStatement 和参数:

String insert = "INSERT INTO HR.tweets (DATE_TIME,USER_NAME,TWEET_BEFORE,TWEET_AFTER) " + 
" VALUES ((select SYSDATE from dual),?,?,?)";
PreparedStatement stmt = connection.prepareStatement(insert);
stmt.setParameter(1, tweet.getUser().getScreenName());
stmt.setParameter(2, tweet.getText());
stmt.setParameter(3, finalstring);
stmt.executUpdate();

【讨论】:

  • 不需要selectVALUES (SYSDATE,?,?,?) 会很好。
【解决方案2】:

使用PreparedStatement 而不是Statement
如果您的任何字段包含引号字符 ('),您的查询将始终失败。
此外,您的查询容易受到 SQL 注入攻击,而 PreparedStatement 可以防止此类攻击。

PreparedStatement 的详细信息可以在本教程中找到:
http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
这是非常非常基础的知识,这里就不解释了。

【讨论】:

  • 非常感谢您的所有回答。我的问题现在解决了:)
【解决方案3】:

这里的问题是您使用了特殊字符,这导致发送到数据库的语句无效。

尝试使用这样的准备好的语句...

PreparedStatement pstatement = null;
Connection connection = null;
    try 
    {

        connection = DriverManager.getConnection(
        "jdbc:oracle:thin:@localhost:1521:" + "XE", "hr","hr");

        if (connection != null) 
        {
            pstatement = connection.prepareStatement("INSERT INTO HR.tweets (DATE_TIME,USER_NAME,TWEET_BEFORE,TWEET_AFTER) VALUES ((select SYSDATE from dual),?,?,?)");


            q2 = q2 + "'" + tweet.getUser().getScreenName() + "'" + ",";
            q2 = q2 + "'" + tweet.getText() + "'" +",";
            q2 = q2 + "'" + finalstring + "')";
            pstatement.setString(1, tweet.getUser().getScreenName());
            pstatement.setString(2,tweet.getText());
            pstatement.setString(3, finalstring);
            pstatement.execute();   

        }
    } 
    catch (SQLException e) 
    {
       e.printStackTrace();
    }finally{
        pstatement.close();
        connection.close();
    }

...prepared statements 通常会处理格式错误的字符串和发送到 DB 的无效引号。

【讨论】:

  • 不需要select sysdateVALUES (SYSDATE,?,?,?) 会很好。另外,您缺少values 子句的结束)
  • 感谢更正 是的,声明缺少“)”
  • 修复了丢失的括号,再次感谢指正
【解决方案4】:

正如@wero 所提到的,查询的问题在于它包含引号(')。要转义它,您可以使用backslash (\)。

Eg: we\'re

然而,正如其他人所建议的那样,使用prepared-statements 更安全,它还可以防止 sql 注入作为奖励!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    相关资源
    最近更新 更多