코드에서 복잡한 SQL 쿼리, 시도, 캐치 및 결선을 처리하는 것보다 execute(SQL, up to three inputs)
메서드가 있지만 결과 집합에 액세스하려고하면 실행 결과가 나옵니다. 오류 :Java SQL 실행 메소드를 사용하지만 결과에 액세스 할 수 있음
"Operation not allowed after ResultSet closed"
.
해결 방법이 있습니까? 내가 생각할 수있는 유일한 방법은
코드에서 복잡한 SQL 쿼리, 시도, 캐치 및 결선을 처리하는 것보다 execute(SQL, up to three inputs)
메서드가 있지만 결과 집합에 액세스하려고하면 실행 결과가 나옵니다. 오류 :Java SQL 실행 메소드를 사용하지만 결과에 액세스 할 수 있음
"Operation not allowed after ResultSet closed"
.
해결 방법이 있습니까? 내가 생각할 수있는 유일한 방법은
나는 이전에 같은 문제가 발생했습니다.
public ArrayList<Map<String, String>> getListOfMapsFromSQL(String sql) throws SQLException {
con = DriverManager.getConnection(url,user,pass);
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>();
rs = stmt.executeQuery(sql);
ResultSetMetaData rsmd = rs.getMetaData();
while(rs.next()){
Map<String, String> fieldsMap = new HashMap<String, String>();
for(int i=1; i<=rsmd.getColumnCount(); i++){
fieldsMap.put(rsmd.getColumnLabel(i), rs.getObject(i).toString());
}
list.add(fieldsMap);
}
list.trimToSize();
stmt.close();
con.close();
return list;
}
가 대신 ResultSet
을 반환하는이지도의 목록을 (1 개 행을 나타내는 각각의) 반환
when you close the PreparedStatement it closes the ResultsSetToo
수정, 당신의 시간을
많은 감사를 저장하는 배열로 변환되었다. 결과를 처리 할 때까지 PreparedStatement를 닫지 않을 수 있습니다.
인터페이스를 정의합니다. ResultConsumer 또는 execute()의 호출자가 구현할 수있는 것과 비슷한 것입니다. 그런 다음 execute() 메서드 내에서 결과 집합을 소비자에게 전달하면됩니다.
public Interface ResultConsumer { void processResult(ResultSet rs); }
그런 다음 실행()이
public void execute(String SQL, ResultConsumer consumer, ... other parameters) { PreparedStatement stmt = ... ResultSet rs = stmt.executeQuery(); consumer.processResult(rs); rs.close(); stmt.close(); }
(나는 명확성을 위해 처리하는 모든 오류 검사 및 예외를 제거, 물론 당신이 처리해야합니다)
이와 같은 마감 처리를하면이 문제를 해결할 수 있습니다. 그래도 데이터를 보관하려면 일반 클로저를 작성하여 결과를 목록
처럼 보일 수 있습니다 잠시 뒤로 나는 똑같은 문제를 다루어야했다. 이 디자인에 대해 숙고 한 후에 우리는 아래처럼 그것을하기로 결정했습니다. 코드 아래 ExecuteRequest
클래스가 사용됩니다에서
private static ExecuteRequest er = new ExecuteRequest();
아래에 주어진 몇 가지 구체적인 이유
public static Properties execute(String string, String[] columnames) throws Exception {
Properties resulProperties = er.executeQuery(string, columnames);
return resulProperties;
}
, 나는 내 수업에서 필드를 만들었습니다.
public Properties executeQuery(String sqlstatement, String[] columnNames) throws Exception {
Properties prop = new Properties();
try {
prop = creteProperty(sqlstatement, columnNames);
} catch (Exception e) {
mlogger.report("Error executing sql statement");
throw (e);
}
return prop;
}
public Properties creteProperty(String sqlstatement, String[] columnNames) throws Exception {
Properties prop = new Properties();
try {
PreparedStatement stmt = ConnectionManager.getInstance().prepareStatement(sqlstatement);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
for (int i = 0; i < columnNames.length; i++) {
String key = columnNames[i];
if (rs.getObject(key) != null) {
String value = (rs.getObject(key).toString());
prop.setProperty(key, value);
} else {
String value = "";
prop.setProperty(key, value);
}
}
}
rs.close();
} catch (Exception e) {
mlogger.report("Error executing sql statement");
throw (e);
}
return prop;
}
이 방법을 해결책으로 사용할 수 있습니다.
반환 된 실제 데이터 유형에 대한 정보가 손실되지 않도록하려면'Map '를 다시 전달해야합니다. 그리고'rs.getObject (1) .toString()'은 테이블에 NULL 값이있는 경우 NullPointerException으로 폭탄을 제거합니다. –
매핑 된 모든 JDBC 유형에는 toString() 메소드가 있습니다. 그리고 null에 대해서는 아무런 문제가 없었습니다. SELECT * Null 값을 가진 DATE 필드가있는 내 테이블 중 하나에서 콘솔에 "null"을 출력합니다. – athspk
물론 toString() 메서드가 있습니다. 그러나 문자열을 "진짜"로 다시 변환하는 것은 문제가 될 수 있습니다.어떤 물체를 다시 변환해야하는지 어떻게 알 수 있습니까? 로케일 (소수 구분 기호, 날짜 형식 등)에 따라 달라지는 기본 서식은 어떻습니까? 이것은 데이터베이스의 varchar 열에 모든 것을 저장하는 것과 같습니다. –