データのテキストファイルへのアンロード
 以下のクラスは、RDBMSにJDBC経由で接続して、指定したSELECT文を発行してデータを検索し、 そのデータをタブ区切りまたはカンマ区切りでテキストファイルに出力(アンロード) することが可能です。タブがカンマでなくてもパーセント区切りや$区切りも可能 (いないいない)、また日本語の文字もJavaのエンコーディングをそのまま使うので、 シフトJISや日本語EUCから選べます。 似たような機能はPHPの方が簡単で、 'websql'スクリプトとして先に作ったものをこのサイトにも載せていますが、 これはそのJava版です。

/**
 * DbcmDirectUnloader.java
 * 2002/11/09
 */
import java.sql.*;
import java.io.*;
import java.util.Properties;
import ushi.util.*;

import oracle.jdbc.driver.*;

/**
 * JDBC経由でRDBMSに接続し、SQL文(SELECT文)を発行して得られた結果集合を
 * タブ区切りなどのテキストファイルに出力する処理を行うクラスです。
 */
public class DbcmDirectUnloader {
  String user;
  String password;
  String hostName;
  int    port = 1521;
  String database;
  String separator = "\t";
  String outputFileName;
  String encoding  = "SJIS";

  String query = null;
  String[] params = null;

  /** コンストラクタ */
  public DbcmDirectUnloader(){}

  /**
   * プロパティをプロパティファイルから読むコンストラクタです。
   * @throws IOException プロパティファイルの読み込み中のI/Oエラーです。
   */
  public DbcmDirectUnloader(String propertyFileName)
  throws IOException {
    loadProperties(propertyFileName);
  }

  /**
   * プロパティをプロパティファイルから読み込みます。
   * プロパティ名は user password hostname port database separator
   * outputfilename encoding query です。
   * (パラメータparamは通常固定で指定することはないと思うので、
   * プロパティファイルからはセットできません)
   *
   * プロパティの一部がファイルで指定されていない場合は、既存の値を
   * 上書きすることはありません。
   *
   * なお、プロパティseparatorには「\t」を指定するとタブ文字の意味に
   * なります。但し\t\tとしてもタブ2コにはならないので注意して下さい。
   *
   * @param fileName パラメータファイル名。絶対パスで指定します。
   */
  public void loadProperties(String fileName) throws IOException {
    Properties p = new Properties();
    FileInputStream fis = new FileInputStream(fileName);
    p.load(fis);
    fis.close();

    String v = p.getProperty("user");
    if(v != null) user = v;
    v = p.getProperty("password");
    if(v != null) password = v;
    v = p.getProperty("hostname");
    if(v != null) hostName = v;
    v = p.getProperty("port");
    if(v != null) port = Integer.parseInt(v);
    v = p.getProperty("database");
    if(v != null) database = v;
    v = p.getProperty("separator");
    if(v != null){
      if(v.equals("\\t")) separator = "\t";
      else                separator = v;
    }
    v = p.getProperty("outputfilename");
    if(v != null) outputFileName = v;
    v = p.getProperty("encoding");
    if(v != null) encoding = v;
    v = p.getProperty("query");
    if(v != null) query = v;
  }

  /** RDBMSに接続する際のログオンユーザIDを指定します。*/
  public final void setUser(String user){
    this.user = user;
  }

  /** RDBMSに接続する際のログオンユーザのパスワードを指定します。*/
  public final void setPassword(String password){
    this.password = password;
  }

  /** 接続するRDBMSが動いているホスト名を指定します。*/
  public final void setHostName(String hostName){
    this.hostName = hostName;
  }

  /** 接続するRDBMSが待機(listen)しているTCP/IPポート番号を指定します。*/
  public final void setPort(int port){
    this.port = port;
  }

  /** 接続するRDBMSの名前(Oracleの場合はSID)を指定します。*/
  public final void setDatabase(String database){
    this.database = database;
  }

  /**
   * テキストファイルに出力する際の、フィールド間に挟むセパレータ文字列を
   * 指定します。通常は "\t" か "," のどちらかです。
   */
  public final void setSeparator(String separator){
    this.separator = separator;
  }

  /**
   * 出力するテキストファイル名を指定します。サーブレット環境では、
   * 通常絶対パスで指定することになるでしょう。
   */
  public final void setOutputFileName(String outputFileName){
    this.outputFileName = outputFileName;
  }

  /**
   * 出力するテキストファイルのエンコーディングを指定します。
   * デフォルトではSJISですが、EUC-JPにすることもできます。
   */
  public final void setEncoding(String encoding){
    this.encoding = encoding;
  }

  /**
   * 検索するSQL文(SELECT文)を指定します。?を使ったSQL文(準備文)
   * にしても構いません。
   */
  public final void setQuery(String query){
    this.query = query;
  }

  /**
   * SQL文が?を含む準備文であるとき、各?に対応する値を文字列としてもつ配列。
   * 要素の数は?の個数と等しくなければなりません。
   * またSQL文が?を含まない場合は、paramsはnullでなければいけません。
   */
  public final void setParams(String[] params){
    this.params = params;
  }

  private Connection connectToDB()
  throws java.sql.SQLException
  {
    DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());

    Connection conn =
      DriverManager.getConnection(
        "jdbc:oracle:thin:@" + hostName + ":" + port + ":" + database,
        user, password);
    return conn;
  }

  /**
   * RDBMSに接続し、検索を行い、データをフェッチしながらテキストファイル
   * に出力します。
   * 必要な情報(プロパティ)は、事前にセットしておく必要があります。
   * 特に検索のためのSQL文(query)と出力データファイル(outputFileName)
   * は必須です。
   */
  public void download()
  throws java.io.IOException, java.sql.SQLException,
         java.io.UnsupportedEncodingException, java.io.FileNotFoundException
  {
    Connection conn = connectToDB();
    Statement stmt = null;
    PreparedStatement pstmt = null;
    ResultSet rset;

    if(params == null){
      stmt = conn.createStatement();
      ((OracleStatement)stmt).setRowPrefetch(100);
      stmt.setFetchSize(100);
      rset = stmt.executeQuery(query);
    }
    else{
      pstmt = conn.prepareStatement(query);
      ((OraclePreparedStatement)pstmt).setRowPrefetch(100);
      pstmt.setFetchSize(100);
      for(int i=0; i<params.length; i++){
        pstmt.setString(i+1, params[i]);
      }
      rset = pstmt.executeQuery();
    }

    ResultSetMetaData rsmd = rset.getMetaData();
    int cols = rsmd.getColumnCount();

    FileOutputStream fos = new FileOutputStream(outputFileName, false);
    OutputStreamWriter w = new OutputStreamWriter(fos, encoding);
    BufferedWriter writer = new BufferedWriter(w);

    while(rset.next()){
      String buffer = "";
      for(int i=0; i<cols; i++){
        if(i > 0) buffer += separator;
        String v = rset.getString(i+1);
        buffer += (v == null) ? "" : v;
      }
      writer.write(buffer + "\n");
    }

    writer.close();
    w.close();
    fos.close();

    rset.close();
    if(stmt != null)  stmt.close();
    if(pstmt != null) pstmt.close();
    conn.close();
  }

  public static void main(String args []) throws SQLException, IOException {
    String[] params = {"200210%"};
    DbcmDirectUnloader unl = new DbcmDirectUnloader("./unloader.properties");
    unl.setParams(params);
    unl.download();
  }
}
// end.

簡単な使い方ですが、

DbcmDirectUnloader unl = new DbcmDirectUnloader();
unl.setHostName("falcon.center.nsnhnkmmkk.co.jp");
unl.setPort(1521);
unl.setDatabase("UDB");
unl.setUser("URANO");
unl.setPassword("URANO398");
unl.setQuery("SELECT * FROM USERS WHERE USERNAME = ?");
unl.setOutputFileName("/the/path/of/unload.dat");
String[] params = {"uranom"};
unl.setParams(params);
unl.unload();

このように、RDBMSに接続するためその他のプロパティ値をセットしていき、 最後にunload()メソッドで指定したファイルにアンロードする方法が一番単純です。 この指定をプログラムの外から読ませたい場合には、 java.util.Properties オブジェクトとして指定する方法があります。 これはmain()メソッドでやっているように、 プロパティファイルのパスをコンストラクタで指定してやればOKです。

user=URANO
password=URANO398
hostname=falcon.center.nsnhnkmmkk.co.jp
port=1521
database=UDB
separator=\t
outputfilename=tmp.dat
encoding=SJIS

query=SELECT * FROM EUC_DB_ESCAPED WHERE DELIVERED_DATE LIKE ?

JDBC and Swing Top

(first uploaded 2002/11/09 last updated (not ever), URANO398)

楽天モバイル[UNLIMITが今なら1円] ECナビでポインと Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!


無料ホームページ 無料のクレジットカード 海外格安航空券 解約手数料0円【あしたでんき】 海外旅行保険が無料! 海外ホテル