2013-12-12 206 views
0

问题是: 无法从表格中插入数据。从错误消息看来,它看起来没有看到第一列。我知道列在那里,数据被插入。我查了数据库。我检查了列Number是否有一些隐藏的空间。不,它不。无法从数据库检索数据

试过: 调试每一行,一切都很好,一起插入数据到数据库。 发现的问题几乎是在代码的末尾:

 rs1.next(); 
     String s1 = rs1.getString(1); 

我试着写

 rs1.first(); 
     String s1 = rs1.getString(1); 

 rs1.first(); 
     String s1 = rs1.getString("Number"); 

下面我贴我的是正常工作的最终代码我可以将数据插入表格并显示在浏览器上。

package mypackage; 
    import java.sql.Connection; 
    import java.sql.DriverManager; 
    import java.sql.PreparedStatement; 
    import java.sql.ResultSet; 
    import java.sql.SQLException; 
    import java.sql.Statement; 
    import java.util.Collections; 
    import java.util.LinkedList; 
    import javax.ws.rs.GET; 
    import javax.ws.rs.Path; 
    import javax.ws.rs.PathParam; 
    import javax.ws.rs.QueryParam; 
    import javax.ws.rs.core.Response; 

    @Path("/query") 
    public class CList { 

     private LinkedList<SMember> contacts; 

     public CList() { 
     contacts = new LinkedList(); 
     } 

     @GET 
     @Path("/{CList}") 
     public Response addCLocation(@QueryParam("employeeId") String eId) throws SQLException{ 

      String dataSourceName = "DBname"; 
      String dbURL = "jdbc:mysql://localhost:3306/" + dataSourceName; 
      String result = ""; 
      Connection con = null; 
      PreparedStatement ps0 = null, ps = null; 
      ResultSet rs = null, rs1 = null; 
      String id = eId; 

      try { 
       try{ 
       //Database Connector Driver 
       Class.forName("com.mysql.jdbc.Driver"); 
       //Connection variables: dbPath, userName, password 
       con = (Connection)  
         DriverManager.getConnection(dbURL,"someusername","somepassword"); 
        System.out.println("We are connected to database"); 
        //SQL Statement to Execute 
        System.out.print(id); 
        s = con.prepareStatement("SELECT 1 FROM CList WHERE Number=?"); 
            s.setString(1, eId); 
        rs = s.executeQuery(); 
        //Parse SQL Response 
        if(!rs.next()) { 
         SMember sm = new SMember(); 
         ps = (PreparedStatement) con.prepareStatement("INSERT 
           INTO Contact_List (Number, First_Name, Last_Name, Phone_Number) " + 
       "VALUES (?,?,?,?)"); 
         ps.setString(1,sm.getEmployeeID()); 
         ps.setString(2,sm.getFirstName()); 
         ps.setString(3,sm.getLastName()); 
         ps.setString(4,sm.getPhone()); 
         ps.executeUpdate(); 
              ps = con.prepareStatement("SELECT Number, First_Name, 
               Last_Name, Phone_Number FROM CList 
               WHERE Number=" + eId); 
        rs1 = ps.executeQuery(); 
        while(rs1.next()){ 
         result = "[Added contact to contact list. 
                   Number: " + rs1.getString(1) + 
          "][First_Name: " + rs1.getString(2) + 
          "][Last_name: " + rs1.getString(3) + 
          "][Phone_Number: " + rs1.getString(4) + 
          "]\n"; 
        } 
        } 
        else { 
         result = "[Contact is already on the list]"; 
        } 
       } 
       catch(Exception e) { 
        System.out.println("Can not connect to database"); 
        e.printStackTrace(); 
       } 
       finally { 
        //Close Database Connection 
        ps0.close(); 
        ps.close(); 
        con.close();  
       } 
      } 
      catch(Exception e) { 
       System.out.println(e); 
      } 
      //Return the Result to Browser 
      return Response.status(1000).entity(result).build(); 
     } 

enter image description here

1234号是唯一的,它是一个数字我想。

你看到号码应该是唯一的。到目前为止,我正在从SMember类中获取数据,并且始终使用相同的数据。我的问题的目的只是为了让我几秒前插入的信息。

此外,还有SMember类,我没有发布在这里,并在其构造函数我初始化号码,名字,姓氏和电话号码。测试目的。 我做了所有建议的更改,但问题依然存在。

+0

PM 77-1您是如何编辑它的?我不想在未来犯同样的错误。 – user1282256

回答

1

这里有几个问题。

你的问题的解决方案是你不让数据库生成密钥,这就是为什么你以后不能要求生成的密钥。

看看这行代码的:

ps = (PreparedStatement) con.prepareStatement("INSERT INTO CList (Number, First_Name, Last_Name, Phone_Number) VALUES ('"+sm.getEmployeeID()+"', '"+sm.getFirstName()+"', '"+sm.getLastName()+"', '"+sm.getPhone()+"')", Statement.RETURN_GENERATED_KEYS); 

以后想检索Number列的值作为一个生成的密钥。但是,您确实会传递该列的值,即返回值sm.getEmployeeID()。如果你传递一个值,它不会被生成(假设这个列在数据库中被定义为自动递增)

解决这个问题并不能解决所有问题,因为你的代码有很多问题。那些我可以直接发现:

  • 您可以通过创建一个新的对象初始化变量SM但是当你无处设置这些值,你仍然没有为员工ID,名字,姓氏或电话号码值。 sm(或者你是否在默认的构造函数中做到这一点?)
  • 你正在尝试使用预准备语句,这很好,但你实际上并没有这样做,这是非常糟糕的,因为它o为SQL注入奠定基础。您不应像创建查询字符串那样创建查询字符串,而应使用固定字符串,例如INSERT INTO CList (Number, First_Name, Last_Name,Phone_Number) VALUES (?,?,?,?),然后在执行该语句之前设置语句上的值。这样,没有人可以通过该语句篡改数据库(在SQL注入中进行阅读,只是通过谷歌来查看你将要介绍的问题)。
  • 您的员工编号似乎是您的方法的eId参数。你应该在你的select语句中使用它来查看它是否已经存在于你的数据库中(这里也使用一个准备好的语句),以后在你的insert语句中当id不在数据库中时。
  • 如果您正在检查特定的ID,然后插入该特定的ID,检索一些生成的ID是非常无用的。您已经定义了您的唯一标识符。使用那个!

编辑:由于你的代码有点乱,我已经清理了一些东西,并修复了我可以直接找到的问题。检查这是否对您有帮助:

public Response addCLocation(String eId) throws SQLException { 

    String dataSourceName = "DBname"; 
    String dbURL = "jdbc:mysql://localhost:3306/" + dataSourceName; 
    String result = ""; 
    Connection con = null; 
    Statement s = null; 
    PreparedStatement ps = null; 
    ResultSet rs = null, rs1 = null; 
    String id = eId; 

    try { 
     try { 
     // Database Connector Driver 
     Class.forName("com.mysql.jdbc.Driver"); 
     // Connection variables: dbPath, userName, password 
     con = DriverManager.getConnection(dbURL, "someusername", "somepassword"); 
     System.out.println("We are connected to database"); 
     s = con.createStatement(); 
     // SQL Statement to Execute 
     System.out.print(id); 
     PreparedStatement alreadyThere = con.prepareStatement("SELECT 1 FROM CList WHERE Number = ?"); 
     alreadyThere.setString(1, eId); 
     System.out.println("0"); 
     // Parse SQL Response 
     int i = 0; 
     if (rs.next() == false) { 
      SMember sm = new SMember(); 
      ps = con 
       .prepareStatement("INSERT INTO Contact_List (Number, First_Name, Last_Name, Phone_Number) VALUES (?,?,?,?)"); 
      ps.setString(1, sm.getEmployeeID()); 
      ps.setString(2, sm.getFirstName()); 
      ps.setString(3, sm.getLastName()); 
      ps.setString(4, sm.getPhone()); 
      ps.executeUpdate(); 
     } 
     else { 
      result = "[Contact is already on the list]"; 
     } 
     } 
     catch (Exception e) { 
     System.out.println("Can not connect to database"); 
     e.printStackTrace(); 
     } 
     finally { 
     // Close Database Connection 
     s.close(); 
     ps.close(); 
     con.close(); 
     } 
    } 
    catch (Exception e) { 
     System.out.println(e); 
    } 
    // Return the Result to Browser 
    return Response.status(200).entity(result).build(); 
    } 
+0

在我编辑的文章中,我做了所有必要的更改。我仍然想要检索它,以了解它是如何工作的。它仍然给我同样的错误,并且很想知道如何解决它。我会尽量使用你的建议中的最后一点。 – user1282256

+0

您没有做所有必要的更改。您的支票仍然没有使用id参数,但String'id'。你应该在那里使用一个准备好的语句来防止sql注入。而且你仍然尝试读取生成的id,这些id在你仍然已经把id作为你的'addCLocation'方法的参数提交给你的时候从未被生成。 – Matthias

+0

添加了真正进行必要更改的代码示例。检查一下它是否接近你真正需要的东西。 – Matthias

0

“SELECT 1 FROM栏列表,其中number =‘身份证’”

它看起来像你想实际选择记录中,其中数值为“身份证”。当您尝试在空的结果集上执行“rs.next()”命令时,可能会导致错误。你是否试图做类似于

“SELECT 1 FROM CList WHERE Number ='”。 ID 。 “'”? “id”是一个变量?

+0

id是一位独特的员工编号 – user1282256

1

您收到此错误是因为您的第一个查询错误,它返回一个空的结果集。

首先,

rs = s.executeQuery("SELECT 1 FROM CList WHERE Number='id'"); 

在你的上面一行代码是不正确的,应该是这样的:

**rs = s.executeQuery("SELECT 1 FROM CList WHERE Number="+id);** 

那么正确的查询将被解雇数据库。

其次,在下面的代码

if(rs.next() == false) { 
        SMember sm = new SMember(); 
        ps = (PreparedStatement) con.prepareStatement("INSERT 
             INTO CList (Number, First_Name, Last_Name, 
             Phone_Number) VALUES ('"+sm.getEmployeeID()+"', 
             '"+sm.getFirstName()+"', '"+sm.getLastName()+"', 
               '"+sm.getPhone()+"')", 
            Statement.RETURN_GENERATED_KEYS); 
        ps.executeUpdate(); 

在上面的代码,你应该初始化SMember,查询当前对象,他们会为空也是当您使用PreparedStatement的你应该使用的查询问题像这样:

**ps = (PreparedStatement) con.prepareStatement("INSERT INTO CList (Number, First_Name, Last_Name,Phone_Number) VALUES (?,?,?,?)",Statement.RETURN_GENERATED_KEYS); 
ps.setString(1,sm.getEmployeeID()); 
ps.setString(2,sm.getFirstName()); 
ps.setString(3,sm.getLastName()); 
ps.setString(4,sm.getPhoneNumber());** 
+0

Mudit,我已经对您提出的更改进行了修改,但仍得到相同的错误。有趣的是数据被插入数据库。我直接去数据库检查它。是越来越插入 – user1282256

+0

数据,因为这种状态检查是错误的 如果(rs.next()==假)应该这样写 如果(rs.next()) 在这种情况下,如果块将不会运行,在逻辑上不会插入记录。因为根据您的代码,您正在从数据库中获取您从函数参数获得的ID的记录。 –

+0

你的意思是这个条件if(rs.next()== false)?如果rs.next()找不到搜索的id将返回false,因为id不存在。它会尝试选择一些员工ID。 executeQuery返回结果集,但从不为空。 – user1282256

1

查询语句也许问题“SELECT 1 FROM栏列表,其中number =‘身份证’”,在SELECT语句您的ID被当作String.we需要用值来代替。

- >试试这样{ “SELECT 1 FROM栏列表,其中number =” + ID},

- >还有一件事 “从表名选1” 将打印1没有行的播映你的状况。

所以我的建议是

{"SELECT * FROM CList WHERE Number="+id} 

试试这个!

+0

我也试过这个,但它的工作方式也是一样。在发布代码之前,我发布了打印声明,第一个请求运行良好。 – user1282256