2012-03-01 179 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注入攻击。)