【问题标题】:JDBC: complains about invalid sign but seems fineJDBC:抱怨无效符号但似乎很好
【发布时间】:2010-12-14 14:11:10
【问题描述】:

我必须使用 JDBC 来写入数据库(hibernate/ibatis 不是一个选项),我的数据库是 Oracle 11g。

我创建以下查询:insert into user(user_id, username, age, creation_ts) values(seq_userid.NEXTVAL, 'Jack', 19,TO_TIMESTAMP('14/12/2010 15/09/46', 'DD/MM/RR HH24/MI/SS'));

但是我的statetement.execeuteUpdate(above sql)。生成无效符号异常。 但是当我在 squirrel 中执行查询时,它会被提交得很好。 有谁知道为什么会这样?


Edit:
user table:
id: number : not null
username varchar2(30) not null
age number(10) not null
creation_ts timestamp not null

Error:
ORA-00911: invalid character

Java snippet:
try
        {       
            DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
            String url = "privatized";
            Connection conn = DriverManager.getConnection(url, "username", "password");

            Statement st = conn.createStatement();

            Format formatter = new SimpleDateFormat(dateTimeFormatString);
            String formattedDate = formatter.format(Calendar.getInstance(TimeZone.getDefault()).getTime()); 

            StringBuilder insertQuery = new StringBuilder("insert into user(user_id, username, age, creation_ts) values(seq_userid.NEXTVAL,");
                insertQuery.append(username);
                insertQuery.append(",");
            insertQuery.append(age);
            insertQuery.append(",TO_TIMESTAMP('");
            insertQuery.append(formattedDate);
            insertQuery.append("', 'DD/MM/RR HH24/MI/SS'));");
            System.err.println(insertQuery.toString());
            st.executeUpdate(insertQuery.toString());

            conn.close();
        } catch (SQLException ex){
            System.err.println(ex.getMessage());
            System.err.println(ex.getCause().toString());
            ex.printStackTrace();
            System.out.println("=========================================");
        } catch(Exception ex) {
            System.err.println(ex.getMessage());
        }

【问题讨论】:

  • 查看相关表格的规格会很有帮助。 Java 代码摘录也会有所帮助。
  • 有oracle异常吗?
  • 什么是无效符号异常?你能粘贴错误/堆栈跟踪吗?
  • 尝试从查询末尾删除分号
  • 从谷歌搜索 ORA-00911 techonthenet.com/oracle/errors/ora00911.php 你是如何建立你的陈述的?页面上的操作 3 可能是您的问题。

标签: java oracle jdbc oracle11g ora-00911


【解决方案1】:

正如我在上面的评论中所说,问题可能是由于 SQL 语句末尾的额外分号造成的。看到这个article

您可能还想查看PreparedStatments,让您的生活更轻松。这将是您上述代码的粗略翻译。我留下了一些部分,很可能有错误。

String query = "insert into user(user_id, username, age, creation_ts) values(?,?,?,?)";
PreparedStatement pstmt = conn.prepareStatement(query);
... //fill in all your parameters
pstmt.setTimestamp(4, new Timestamp(System.currentTimeMillis()) );
... //execute here

【讨论】:

  • 叹息,确实和那个用户一样的错误。为如此愚蠢的事情进行了数小时的调试。而且我没有在文档中读到任何关于此的内容...有时好习惯会变得很糟糕...
  • 我在 2 个月前经历了同样的事情,然后找到了那个链接。容易犯错误。
  • 感谢您的 setTimeStamp 提示。这确实减少了相当多的代码行,并大大提高了可读性。
【解决方案2】:
TO_TIMESTAMP('14/12/2010 15/09/46', 'DD/MM/RR HH24/MI/SS')

您发送了一个 4 位数的年份,但格式字符串定义了一个 2 位数的年份(无世纪)

试试这个:

insertQuery.append("', 'DD/MM/RRRR HH24/MI/SS'));");

【讨论】:

  • 刚刚试了,还是没有解决,还是谢谢你的建议。
【解决方案3】:

您确定username 变量的值是'Jack' 而不是Jack? (ORA-00911 错误看起来不像典型的日期格式错误)。

您还应该了解PreparedStatement。它们更高效、更易于阅读和调试,并且不易受到 SQL 注入的影响。

我的 java 有点生锈了,但是如果使用 PreparedStatement,它看起来像这样:

String query = "insert into user(user_id, username, age, creation_ts) values "
              + "(seq_userid.NEXTVAL, ?, ?, ?)";

Statement st = conn.prepareStatement(query);

st.setString(1, username);
st.setInt(2, age);
st.setTimestamp(3, new java.sql.Timestamp(
                          Calendar.getInstance(
                             TimeZone.getDefault()).getTimeMillis()));

st.executeUpdate(insertQuery.toString());

这样,您无需将日期转换为字符串即可让数据库将其转换回。此外,您可能会发现该声明更易于阅读,并且您永远不必担心用户将他们的帐户命名为 with a ' (single-quote) :)

【讨论】:

  • 你好文森特,我确定它可以解决杰克。我打印了 sql 语句,这就是我得到的结果。我会看看 PreparedStatements。老实说,我不经常使用 JDBC。我更熟悉hibernate/Ibates,我可以在其中设置值。
  • @jack: 正如Sean 指出的那样,这看起来不像是日期格式错误。 PreparedStatement 绝对是要走的路,我希望你看看:)(我已经用一个例子更新了我的答案)
  • 我一定会的。老实说,我已经忘记了他们。休眠过多。
猜你喜欢
  • 2014-06-14
  • 2017-05-24
  • 1970-01-01
  • 2017-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
  • 1970-01-01
相关资源
最近更新 更多