2010-12-14 36 views
1

我必须使用JDBC写入数据库(hibernate/ibatis不是一个选项),我的数据库是Oracle 11g。JDBC:抱怨无效标志,但似乎很好

创建以下查询: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)。生成无效的符号异常。 但是,当我在松鼠中执行查询它得到承诺很好。 有谁知道为什么会发生这种情况?


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()); 
     } 
+0

这将有助于查看有关表格的规格。 Java代码摘录也可能有帮助。 – Jules 2010-12-14 14:15:41

+0

它有一个oracle异常吗? – HamoriZ 2010-12-14 14:16:20

+0

什么是无效符号异常?你可以粘贴错误/堆栈跟踪? – 2010-12-14 14:19:00

回答

2

正如我在上面发表评论时,问题可能是由于在您的末尾添加了额外的分号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 
+1

感叹,确实和那个用户一样的错误。调试的时间非常愚蠢。而且我在文档中没有读到任何有关这方面的信息......有时好的问题会变得很糟糕...... – jack 2010-12-14 15:19:04

+0

2个月前,我经历了同样的事情,然后发现该链接。容易犯错。 – Sean 2010-12-14 15:29:31

+0

并感谢您的setTimeStamp提示。这确实可以削减代码的几行内容,并提高了可读性。 – jack 2010-12-14 15:35:17

0
TO_TIMESTAMP('14/12/2010 15/09/46', 'DD/MM/RR HH24/MI/SS') 

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

试试这个:

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

刚刚尝试过,它没有解决它,但谢谢你的建议。 – jack 2010-12-14 14:42:53

0

您确定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()); 

这样你就不需要一个日期转换为字符串把它转换回用D B。您也可能会发现该语句更容易阅读,您将永远不必担心用户的帐户名称with a ' (single-quote) :)

+0

你好文森特,我敢肯定,它解决了杰克。我打印了sql语句,这就是我得到的结果。我会给PreparedStatements一看。坦率地说,我不经常使用JDBC。我更熟悉hibernate/ibates,我可以设置这些值。 – jack 2010-12-14 14:58:07

+0

@jack:作为[肖恩](http://stackoverflow.com/questions/4440022/jdbc-complains-about-invalid-sign-but-seems-fine/4440482#4440482)指出,这看起来不像一个日期格式错误。 PreparedStatement定义了要走的路,我希望你能看看:)(我用例子更新了我的答案) – 2010-12-14 15:19:15

+0

我当然会。坦率地说,我忘记了他们。冬眠太多。 – jack 2010-12-14 15:36:00