我试图在表中执行相对简单的插入,但是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/