2012-03-01 175 views
0

我正在嘗試爲此按鈕編寫一個函數。我希望能夠傳遞一個文本域的值,並能夠進入我的數據庫檢索一些信息.....Oracle Java SQL異常錯誤:ORA-0094

有人可以向我解釋發生了什麼,併爲我提供了一個解決這個瘋狂?

謝謝大家的xD

我一直運行到這個愚蠢的問題:

ACTION1 [email protected] 

Exception:java.sql.SQLSyntaxErrorException: ORA-00904: "ART": invalid identifier 

代碼:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           
    // TODO add your handling code here: 
    //CLASS TYPE 
    //LIST ALL OFFERED CLASSES AND REVENUE 


    try{ 
     String classtype = jTextField1.getText().trim(); 
     if(classtype.equals("")){ 
      JOptionPane.showMessageDialog(this, "Sorry Wrong input.... Please try again...."); 
     } 
     else if(classtype != ""){ 
      try 
      { 
        Class.forName("oracle.jdbc.driver.OracleDriver"); 
        Connection conn=DriverManager.getConnection(
        "jdbc:oracle:thin:@fourier.cs.iit.edu:1521:orcl", 
        "usr","pwd"); 
        Statement stmt = conn.createStatement(); 
        System.out.println("ACTION1 created"+conn+"\n\n"); 


        String ct = jTextField1.getText().trim(); 
        //String aa = "SELECT * FROM CLASS WHERE TYPE="+classtype; 
        //System.out.println(aa); 

        ResultSet rset = stmt.executeQuery("SELECT * FROM CLASS WHERE TYPE="+ct); 
        while (rset.next()) { 
         System.out.println(rset.getString("TITLE") + " "); 
        } 

        JOptionPane.showMessageDialog(this, "Class Type: "+classtype); 


        stmt.close(); 
        conn.close(); 
        System.out.println("Connection Closed"); 
      } 
      catch(Exception sqle){ 
        System.out.println("\nException:"+sqle); 
      } 
     } 
    } 
    catch(Exception e){ 
     JOptionPane.showMessageDialog(this, "Please Retry input....", "Error", JOptionPane.ERROR_MESSAGE); 
    } 

} 
+0

您的文本框的內容添加到您的SQL字符串(絕對NOGO SQL注入漏洞!),那麼什麼是'ct'的內容時,會拋出異常? – 2012-03-01 09:04:56

+0

as @Andreas_D表示您沒有使用準備好的語句。但無論如何,如果你連接一個字符串,它需要在兩個'''內,'''SELECT * FROM CLASS WHERE TYPE ='「+ ct +」'「'(但更好的解決方案是將params添加到準備好的語句 – 2012-03-01 09:14:12

回答

2

您將值作爲查詢的一部分傳遞,並且您正在處理的字符串串聯使SQL分爲:

SELECT * FROM CLASS WHERE TYPE=ART 

(其中ARTct從文本框的值),所以它試圖找到在表中的列稱爲ART。在絕對你至少需要引用字符串:

ResultSet rset = stmt.executeQuery("SELECT * FROM CLASS WHERE TYPE='" + ct + "'"); 

可是真的不這樣做;正如@Andreas_D所說,你已經開放給SQL注入了。始終使用準備好的語句和綁定變量:

String sql = "SELECT * FROM CLASS WHERE TYPE=?"; 
PrepareStatement stmt = conn.prepareStatement(sql); 
stmt.setString(1, ct); 
ResultSet rset = stmt.executeQuery(); 
3

讓我猜...沒有了ct字符串開始與「ART 「(或一些變化)?

如果是這樣,問題是SQL需要引號圍繞字符串文字。您的查詢可能看起來甲骨文是這樣的:

SELECT * FROM CLASS WHERE TYPE=Art of War 

,但它應該看起來像

SELECT * FROM CLASS WHERE TYPE='Art of War' 

有兩種方法來解決這個問題:

  1. 組裝用引號字符查詢大約在ct

  2. 收件查詢作爲"SELECT * FROM CLASS WHERE TYPE=?",使用PreparedStatement代替Statement並使用setString方法中提供的參數值。

如果做得好,第二種方法更安全,效率更高。 (使用字符串打擊查詢和使用Statement的問題是您可能使自己容易受到SQL注入攻擊。)