Java/SQL -executeUpdate() 挂起并导致 OutOfMemoryException

标签 java sql sql-server jdbc

我试图在表中执行相对简单的插入,但是executeUpdate() 方法会挂起,直到程序因OutOfMemoryException 崩溃。我已成功在 SQL Server Management Studio 上执行插入,并且已将数据库设置为脱机并重新联机,因此我认为没有任何方法可以锁定表。我还打印了我的 token ,它们都不为空。

我的代码中有什么可疑的地方吗?

if(commandCode.equals("RV")){
    StringTokenizer tokens = new StringTokenizer(fullLine,"^");

    String itemCallNumber=null;
    String itemCurrentLocation=null;
    String itemFormat=null;
    String itemHomeLocation=null;
    String itemLibrary=null;
    String itemType=null;
    String itemCat1=null;
    String itemCat2=null;
    String itemCat3=null;
    Integer itemPubYear=null;
    String stationLibrary=null;
    String userProfileName=null;
    String userCat1=null;
    String userCat2=null;       
    String userZipCode=null;
    String userLibrary=null;
    java.sql.Date userBirthdate=null;
    String clientType = null;


    while(tokens.hasMoreTokens()){
        String token = tokens.nextToken();
        System.out.println(token);
        if(token.startsWith("UZ")){
            String dateString = token.substring(2);
            SimpleDateFormat format = new SimpleDateFormat("M/d/yyyy");
            Date date = format.parse(dateString);

            userBirthdate=new java.sql.Date(date.getTime());;
        }
        if(token.startsWith("PG")){
            userCat1=token.substring(2);
        }
        if(token.startsWith("PH")){
            userCat2=token.substring(2);
        }

        if(token.startsWith("PE")){
            userProfileName=token.substring(2);
        }

        if(token.startsWith("UM")){
            userLibrary=token.substring(2);
        }
        if(token.startsWith("UB")){
            userZipCode=token.substring(2);
        }

        if(token.startsWith("IQ")){
            itemCallNumber=token.substring(2);
        }
        if(token.startsWith("IL")){
            itemCurrentLocation=token.substring(2);
        }
        if(token.startsWith("IK")){
            itemFormat=token.substring(2);
        }
        if(token.startsWith("IN")){
            itemHomeLocation=token.substring(2);
        }
        if(token.startsWith("NS")){
            itemLibrary=token.substring(2);
        }
        if(token.startsWith("IG")){
            itemType=token.substring(2);
        }
        if(token.startsWith("NX")){
            itemCat1=token.substring(2);
        }
        if(token.startsWith("NY")){
            itemCat2=token.substring(2);
        }
        if(token.startsWith("0A")){
            itemCat3=token.substring(2);
        }
        if(token.startsWith("IF")){
            itemPubYear=Integer.parseInt(token.substring(2));
        }
        if(token.startsWith("FE")){
            stationLibrary=token.substring(2);
        }

        if(token.startsWith("dC")){
            clientType=token.substring(2);
        }

    }


    String insert = "INSERT INTO dbo.RenewItem Values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    PreparedStatement insertPS = connection.prepareStatement(insert);

    //These come from earlier in the code and are verified to be correct
    insertPS.setInt(1, id);
    insertPS.setTimestamp(2, ts);

    insertPS.setString(3, itemCallNumber);
    insertPS.setString(4, itemCurrentLocation);
    insertPS.setString(5, itemFormat);
    insertPS.setString(6, itemHomeLocation);
    insertPS.setString(7, itemLibrary);
    insertPS.setString(8, itemType);
    insertPS.setString(9, itemCat1);
    insertPS.setString(10, itemCat2);
    insertPS.setString(11, itemCat3);
    insertPS.setInt(12, itemPubYear);
    insertPS.setString(13, stationLibrary);
    insertPS.setString(14, userProfileName);
    insertPS.setString(15,userCat1);
    insertPS.setString(16, userCat2);
    insertPS.setString(17, userZipCode);
    insertPS.setString(18, userLibrary);
    insertPS.setDate(19, userBirthdate);
    insertPS.setString(20,clientType);

    insertPS.executeUpdate();

编辑:我已经能够极大地隔离问题。它与大表上的周围 SELECT * 有关。在下面的代码中,到达了 selectPS.close() 但该方法永远不会返回。

        final Connection connection = DriverManager.getConnection(url);

        String select = "SELECT * FROM dbo.SirsiStat";
        PreparedStatement selectPS = connection.prepareStatement(select);
        ResultSet rs = selectPS.executeQuery();
        System.out.println("here");
        selectPS.close();

最佳答案

首先,您必须必须处理 JDBC 资源,然后尝试了解 PreparedStatement 的正确使用或用途。

使用 try-with-resource 语法。此语法确保即使在发生异常后也能调用 close() 方法。

try(Connection cn=DriverManager.getConnection(url,user,pass)) {
  //statements

   String sql = "insert into tableName (columnOne, columnTwo) values (?,?)";
   try(PreparedStatement ps = cn.prepareStatement(sql)) {

      while(tokens.hasMoreTokens()) {
         //statements
        ps.setInt(1,valueForColumn1);
        ps.setString(2,valueForColumn2);
      }
   }
}

引用主题 - How to properly dispose of Connection, ResultSet, and Statement objects in a while loop?

关于Java/SQL -executeUpdate() 挂起并导致 OutOfMemoryException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28215761/

相关文章:

java - LIMIT 和 OFFSET 在 android 中不能正常工作

java - 打印多个类

sql - HQL/JPQL - FROM 上的嵌套选择

java - 在通用堆栈类中创建通用堆栈

sql - 为什么比较 varchar/number 有效

sql - 当一张表没有记录时进行多表查询

asp.net - 将数据插入 XML 数据类型的列

mysql - 链接服务器 - 可以看到表但看不到列

sql - 字符串 (dd/mm/yyyy) 日期 sql server

java - 从 Android 移动应用程序连接到笔记本电脑上的数据库