2010-12-14 63 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