Java SQL异常无效的游标状态 - 没有当前行

时间:2013-05-15 22:55:46

标签: java derby sqlexception

我一直在努力解决这个问题。首先,我有一个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 个答案:

答案 0 :(得分:7)

您需要先致电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;
}

答案 1 :(得分:0)

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