忘れられたステージオブジェクト


最近、マルチスレッド一括を修正してスタティックレポートに関する問題を作成した際に、問題が発生したので、忘れたstatementオブジェクトを振り返ってみます。
問題の説明:生成すべき静的なレポートを取得する際に、データベースを接続してSttementオブジェクトを作成し、executeQuery(sql)方法を呼び出してResultSet結果セットに戻り、それから循環的に対応するレコードを取り出します。パクリテストコードは以下の通りです。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
public class ResultSetTest {

     public static void main(String[] args) {
		
	String sql1=" select * from LKG_SR_EXCEL_TASK ";		
        Connection conn=null;
	Statement stmt=null;
	ResultSet rs=null;
	ResultSet rsProc=null;
		
    try{
    	  Class.forName("oracle.jdbc.driver.OracleDriver");
          conn=DriverManager.getConnection("jdbc:oracle:thin:@192.168.23.45:1521:ORABI","portal","portal123");
          
		  stmt=conn.createStatement();
		  rs=stmt.executeQuery(sql1);
		  int i = 0;
		  while(rs.next()){
			System.out.println("i = "+ i++);
			rsProc=stmt.executeQuery(sql1)<span style="color:#000000;">;</span>
			int j =0;
			while(rsProc.next()){
				System.out.println("j = "+ j++);
			}			
		  }
    	}catch(Exception e){
    		System.out.println("       !");
    	}finally{
			try{
				if(rs!=null){
					rs.close();
				}
				if(stmt!=null){
					stmt.close();
				}
				if(conn!=null){
					conn.close();
				}
			}catch(Exception e){
				System.out.println("         !");
			}
		}
	}
}
rs結果集は複数のデータであるべきだが、rs.next()は集合中の第1条を取り出すしかない。しかし、rsProc.next()は記録に行くのが正常である。
 
問題解決の方式:1.statement対象Sttement stmt 2=nullを追加します。2.rsProc=stmt.executeQuery(sql 1)を以下のように修正します   stmt 2=conn.createment()   rsProc=stmt 2.executeQuery(sql 1)
3.finallyに下記を追加します。   if(stmt 2!=null){      stmt 2.lose();   } プログラムが正常に動作します。
 
考えた結果、statementは静的SQL文を実行して結果を生成したオブジェクトに戻すために使用されます。デフォルトでは、同じ時間に各Statimentオブジェクトは一つのResultSetオブジェクトしか開けられません。したがって、SQL statementはsql実行中の流れを作成します。ResultSetオブジェクトを読み込むと読み取りが別のオブジェクトと交差する場合、この2つのオブジェクトは必須です。異なるSttementオブジェクトによって生成されました。現在のResultSetオブジェクトがあると、Sttementインターフェースのすべての実行方法が暗黙的に閉じられます。ここのResultSetオブジェクトはデフォルトです。ResultSetオブジェクトは更新できません。前に移動するポインタしかありません。したがって、一回だけ繰り返します。最初の行から最後の行までしかできません。行の順序は、スクロール可能および/または更新可能なResult Setオブジェクトを生成することができます。以下のコードセグメント(conは有効なConnectionオブジェクト)は、スクロール可能で他の更新に影響されない、更新可能な結果セットをどのように生成するかを示します。
       Sttement stmt=c.reatement(                                      Result Set.TYPEは、                                      Result Set.C.OCUR_UPDDATABLE;       ResultSet rs=stmt.executeQuery(「SELECT a,b FROM TABLE 2」);
修正前のrsProc=stmt.executeQuery(sql 1)、中stmtは再作成されていませんので、rsProcオブジェクトアドレスは変更されていません。rsProckが記録を繰り返した後、対象中の指示記録の針はすでに結果集の末尾を指しています。結果集rsが再びnext()に戻ったのはfalseで、結果の最初のレコードだけを取り出します。
  
1、Steementオブジェクトを作成する
      特定のデータベースへの接続が確立されたら、この接続でSQL文を送信することができます。SttementオブジェクトはConnectionの方法でcreatestatementを作成します。下記のコードセグメントに示されています。
 
      Connection con=DriverManager.get Connection;
      Sttement stmt=c.reatement()
 
Sttementオブジェクトを実行するために、データベースに送信されたSQL文をパラメータとしてSttementに提供する方法:
      ResultSet rs=stmt.executeQuery(「SELECT a,b,c FROM Table 2」);
2、Steementオブジェクトを使ってステートメントを実行する
      SttementインターフェースはSQL文を実行する3つの方法を提供しています。executeQuery、executeUpdate、executute。どの方法を使用するかはSQL文によって生成された内容によって決まります。方法executeQueryは、SELECT文などの単一の結果セットを生成するための文です。
      方法executeUpdateは、INSERT、UPDATEまたはDELETE文、およびSQL DDL文、例えばCREATE TABLEとDROP TABLEを実行するために使用されます。INSERT、UPDTEまたはDELETE文の効果は、修正表のゼロ行または複数行のうちの一列または複数列です。executeUpdateの戻り値は整数であり、カウントアップに影響を与える行数です。CREATE TABLEやDROP TABLEなどの不操作行の文に対しては、executeUpdateの返却値は総じてゼロです。複数の結果セットを返す、複数の更新カウントまたは2つの組み合わせを返す文を実行するためにexecuteは使用します。実行文のすべての方法は、呼び出したSttement対象の現在のオープン結果セットをオフにします。(存在すれば)このことは、Sttementオブジェクトを再実行する前に、現在のResultSetオブジェクトに対する処理を完了する必要があるということです。
     Sttementインターフェースのすべての方法を継承したPreparedSttementインターフェースは、自分のexecuteQuery、executeUpdate、execute方法があります。Sttementオブジェクト自体はSQL文を含まないので、Sttement.executeメソッドにSQL文をパラメータとして提供しなければなりません。PreparedStredStatitementオブジェクトは、これらのパラメータとしません。これらのためにあらかじめコンパイルされたSQL文が含まれています。CallableStationオブジェクトはこれらの方法を継承するためのPreparedStation形式です。これらの方法のためのPreparedSttementまたはCallable Stationバージョンは、クエリパラメータを使用してSQLExceptionを抛り出します。
3、文の完成
      接続が自動送信モードにある場合、実行されたステートメントは完了時に自動的に送信または復元されます。ステートメントは実行され、すべての結果が返ってきたら完了したと考えられます。結果セットを返すためのexecuteQuery方法については、ResultSetオブジェクトのすべての行を検索した時点で文は完了します。方法についてはexecuteUpdateを実行しますが、ステートメントは完了します。少数の呼び出し方法executeの場合は、すべての結果セットまたはそれが生成した更新カウントを検索した後に文が完成します。
 
4、statementの対象をクローズする
SttementオブジェクトはJavaごみ収集プログラムによって自動的にクローズされます。良いプログラミングスタイルとして、Sttementオブジェクトが必要でない時に、明示的にオフにします。これは直ちにDBMSリソースをリリースします。潜在的なメモリ問題を避けるのに役立ちます。
 
以上に間違いがあったら指摘してください。ありがとうございます。
プログラミングの中で楽しみを探して、楽しみの中で自由にプログラミングします!