有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

derby Java SQL异常无效游标状态无当前行

我一直很难弄明白这一点。首先,我有一个insertProduct(Product p)方法,用来检查数据库中是否存在具有指定代码的产品。如果是,此方法将显示错误消息。否则,它应该将产品添加到数据库并将其打印到控制台。我不确定我这样做是否正确

其次,deleteProduct(Product p)方法应该删除由insertProduct方法添加的产品。现在的问题是,当我尝试添加产品时,我一直得到一个SQL异常,然后deleteProduct方法每次运行程序时都会一个接一个地删除数据库中的产品,直到剩下非产品为止。我不确定这两种方法都有什么问题

控制台输出:

Derby has been started.

Product list:
bvbn    Murach's Beginning Visual Basic .NET        $49.50
cshp    Murach's C#                                 $49.50
java    Murach's Beginning Java                     $49.50
jsps    Murach's Java Servlets and JSP              $49.50
mcb2    Murach's Mainframe COBOL                    $59.50
sqls    Murach's SQL for SQL Server                 $49.50
zjcl    Murach's OS/390 and z/OS JCL                $62.50

First product:
bvbn    Murach's Beginning Visual Basic .NET        $49.50

Last product:
zjcl    Murach's OS/390 and z/OS JCL                $62.50

Product by code: cshp
cshp    Murach's C#                                 $49.50

Insert test: 
java.sql.SQLException: Invalid cursor state - no current row.
Product list:
bvbn    Murach's Beginning Visual Basic .NET        $49.50
cshp    Murach's C#                                 $49.50
java    Murach's Beginning Java                     $49.50
jsps    Murach's Java Servlets and JSP              $49.50
mcb2    Murach's Mainframe COBOL                    $59.50
sqls    Murach's SQL for SQL Server                 $49.50
zjcl    Murach's OS/390 and z/OS JCL                $62.50

Delete test: 
zjcl    Murach's OS/390 and z/OS JCL                $62.50

Product list:
bvbn    Murach's Beginning Visual Basic .NET        $49.50
cshp    Murach's C#                                 $49.50
java    Murach's Beginning Java                     $49.50
jsps    Murach's Java Servlets and JSP              $49.50
mcb2    Murach's Mainframe COBOL                    $59.50
sqls    Murach's SQL for SQL Server                 $49.50

Derby has been shut down.

代码:

   import java.sql.*;

public class DBTesterApp
{
private static Connection connection = null;
private static Product p = null ;
public static void main(String args[])
{
    // get the connection and start the Derby engine
    connection = MurachDB.getConnection();
    if (connection != null)
        System.out.println("Derby has been started.\n");

    // select data from database
    printProducts();
    printFirstProduct();
    printLastProduct();
    printProductByCode("cshp");

    // modify data in the database
     p = new Product("test", "Test Product", 49.50);        
    insertProduct(p);
    printProducts();

    deleteProduct(p);
    printProducts();

    // disconnect from the database
    if (MurachDB.disconnect())
        System.out.println("Derby has been shut down.\n");
 }

 public static void printProducts()
 {

   // Product p = null ;
    try (Statement statement = connection.createStatement();
         ResultSet rs = statement.executeQuery("SELECT * FROM Products"))
    {            


        System.out.println("Product list:");
        while(rs.next())
        {
            String code = rs.getString("ProductCode");
            String description = rs.getString("Description");
            double price = rs.getDouble("Price");

         p = new Product(code, description, price);

            printProduct(p);
        }
        System.out.println();
    }
    catch(SQLException e)
    {
        e.printStackTrace();  // for debugging
    }
  }

  public static void printFirstProduct()
  {

     try(Statement statement = connection.createStatement(
             ResultSet.TYPE_SCROLL_SENSITIVE,
             ResultSet.CONCUR_UPDATABLE);

         ResultSet rs = statement.executeQuery("SELECT * FROM Products")){

         System.out.println("First product:");

         rs.first();
         rs.last();

         if(rs.isFirst() == false){
          rs.previous();
         }

         if(rs.isLast() == false){
             rs.next();
         }

         rs.absolute(1);
         String code = rs.getString(1);
         String description = rs.getString(2);
         double price = rs.getDouble(3);

         p = new Product(code , description , price);
         printProduct(p);
         System.out.println();
     }

     catch(SQLException e){
          e.printStackTrace();
         }
  }

 public static void printLastProduct()
 {
     try(Statement statement = connection.createStatement(
             ResultSet.TYPE_SCROLL_SENSITIVE,
             ResultSet.CONCUR_UPDATABLE);

         ResultSet rs = statement.executeQuery("SELECT * FROM Products")){
         System.out.println("Last product:");


         rs.first();
         rs.last();

         if(rs.isFirst() == false){
          rs.previous();
         }

         if(rs.isLast() == false){
             rs.next();
         }

         rs.absolute(7);
         String code = rs.getString(1);
         String description = rs.getString(2);
         double price = rs.getDouble(3);

         p = new Product(code, description, price);
         printProduct(p);
         System.out.println();



     }

     catch(SQLException e){
         e.printStackTrace();
     }
}

  public static void printProductByCode(String productCode)
  {

       String sql  = 
           "SELECT ProductCode, Description, Price " + 
           "FROM  Products "  +    
           "WHERE ProductCode = ?";

   try(PreparedStatement ps = connection.prepareStatement(sql);){

       ps.setString(1, productCode);
       ResultSet rs = ps.executeQuery();

       if(rs.next()){   
         String description = rs.getString("Description");
         double price = rs.getDouble("Price");
         p = new Product(productCode, description, price);
         System.out.println("Product by code: " + productCode);
         printProduct(p);
        }
          else{
          rs.close();
              }

   }


   catch(SQLException e){
    System.err.println(e);

   }


    System.out.println();
  }

  public static void insertProduct(Product p)
  {
    System.out.println("Insert test: ");


    //check if product code exists in database
   try(Statement statement = connection.createStatement();
        ResultSet rs = statement.executeQuery("SELECT * FROM Products")){

   String code =   rs.getString(1);


  if (p.getCode().equals(code) ){
       System.out.println("Error: This product is already in the database!");
       } 


    else{
    String sql = 
            "INSERT INTO Products (productCode, Description, Price) " +
            "VALUES (?, ?, ?)";

    try(PreparedStatement ps = connection.prepareStatement(sql)){


        ps.setString(1, p.getCode());
        ps.setString(2, p.getDescription());
        ps.setDouble(3, p.getPrice());
        ps.executeUpdate();
       }


     catch(SQLException e){
          System.err.println(e);
      } 


    } //end else

      printProduct(p);
    System.out.println();

   }//end try


        catch(SQLException e ){
        System.out.println(e);
         } 
}

 private static void deleteProduct(Product p)
{
    System.out.println("Delete test: ");

    String sql = "DELETE FROM Products " +
                 "WHERE ProductCode = ?";

    try(PreparedStatement ps = connection.prepareStatement(sql)){
        ps.setString(1, p.getCode());
        ps.executeUpdate();

    }

    catch(SQLException e){
       System.err.println(e);
    }
    // add code that deletes the specified product from the database
    // if a product with the specified code doesn't exist, display an error message

    printProduct(p);
    System.out.println();
}

// use this method to print a Product object on a single line
private static void printProduct(Product p)
{
    String productString =
        StringUtils.padWithSpaces(p.getCode(), 8) +
        StringUtils.padWithSpaces(p.getDescription(), 44) +
        p.getFormattedPrice();

    System.out.println(productString);
}
}

共 (2) 个答案

  1. # 1 楼答案

    在检索列值之前,需要调用ResultSet.next()

    // check if product code exists in database
    try(Statement statement = connection.createStatement();
         ResultSet rs = statement.executeQuery("SELECT * FROM Products")){
    if (rs.next()) // THIS is MISSING!
        String code =   rs.getString(1);
    

    上面的代码运行时不会出现异常,但在逻辑上仍然会失败,因为您正在选择所有产品,并且只检查数据库返回的第一个产品的代码。检查产品是否已存在的正确方法是

    // check if product code exists in database
    try(Statement statement = connection.createStatement();
        ResultSet rs = statement.executeQuery(
            "SELECT * FROM Products WHERE ProductCode = '" + p.getCode() + "'")){
    if (rs.next()) {
       System.out.println("Error: This product is already in the database!");
       return;
    }
    
  2. # 2 楼答案

    在insertProduct方法中,在从ResultSet获取数据之前,需要调用ResultSet上的next()方法