2013-12-12 79 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