JDBC 応用

JDBC 応用

  1. JDBC の効率化
  2. JDBC の ConnectionPooling を使う
  3. JDBC でのログの取得方法
  4. JDBC での様々な接続の仕方
  5. BLOB の例
  6. java から PL/SQL パッケージを使う例
  7. JDBC のいろいろな使い方
    1. Connect.java
    2. DBInfo.java
    3. Resources.java
    4. Register.java
    5. tydbpj2/util/resources/dbinfo.properties
  8. JDBC 固有の oracle エラー一覧

JDBC 基礎

  1. Java とデータベース
  2. JDBC のクラス
  3. JDBC ドライバのタイプ
  4. JDBC ドライバを使うための設定
  5. JDBC ドライバと oracle java パッケージの関係
  6. JDBC の使い方
  7. 例: oracle jdbc OCI8 ドライバでの接続:log
  8. 例: oracle jdbc THIN ドライバでの接続
  9. JDBC のバージョンを知るには?
  10. JDBC-ODBC ブリッジ

  1. JDBC の効率化
  2. 一般的に thin は oci より遅い。それは thin は 100% java で書かれているからです。 しかし、効率を上げる方法がいくつかありますので、紹介します。

    1. 繰り返して使う SQL 文は1 PrepareStatement を使用する。

      import java.sql.*;
      
        String upd_stmt = "update emp set salary = salary - 500";
      

    2. TCP の Nagle バッファリングを使用する。

      import java.util.*;
      
         Properties  info = new java.util.Properties();
         info.setProperty("user",    usr);
         info.setProperty("password",pwd);
         info.setProperty("TCP.NODELAY", "YES");
      
         conn = DriverManager.getConnection(url, info);
      

  3. JDBC の ConnectionPooling を使う
  4. Oracle 9i からは $ORACLE_HOME/jdbc/lib/classes12dms.jar を CLASSPATH に指定すると、oracle 社提供の ConnectionPooling 機能を使用できます。 ただし javax.naming 機能を使うため $ORACLE_HOME/jlib/jndi.jar (Sun 提供)も CLASSPATH に追加する必要があります。

    基本的な接続方法と設定は、以下のとおりです。

    static String URL_THIN   = "jdbc:oracle:thin:@bach:1817:ora817";
    static String USERNAME   = "scott", PASSWD = "tiger";
    static final int  MAX_CONN   = 5;
    static final int  MIN_CONN   = 1;
    static final long TIME_LONG  = 60L;       // 60 sec
    static final long TIME_MIDL  = 30L;       // 30 sec
    static final long TIME_SHORT = 1L;        // 1 sec
    static final int  SCHME      = OracleConnectionCacheImpl.DYNAMIC_SCHEME;
    
    OracleConnectionCacheImpl con = new OracleConnectionCacheImpl();
    
    con.setDriverType("thin");
    con.setURL(URL_THIN);
    con.setUser(USERNAME);
    con.setPassword(PASSWORD);
    
    // Set schme
    con.setCacheScheme (SCHME);
    // Set the Max/Min limit of connection pooling
    con.setMaxLimit (MAX_CONN);
    con.setMinLimit (MIN_CONN);
    // Set 
    con.setCacheInactivityTimeout(TIME_LONG);
    con.setCacheTimeToLiveTimeout(TIME_MIDL);
    con.setCacheFixedWaitTimeout(TIME_SHORT);
    con.setCacheFixedWaitIdleTime(TIME_SHORT);
    con.setThreadWakeUpInterval(TIME_SHORT);      // interval to check timeout
    

    ここでキャッシュ方法を setCacheScheme() で設定しますが、DYNAMIC_SCHEME、 FIXED_WAIT_SCHEME、FIXED_RETURN_NULL_SCHEME の3種類があります。

    各種タイマは、キャッシュ方法を指定した後に設定します。 またタイマの単位は秒です。

    キャッシュ方法説        明
    DYNAMIC_SCHEME
    =1
    setMaxLimit() で設定した値以上に接続できますが、 使用終了すると解放されます。 また setCacheTimeToLiveTimeout() を超えると超過分の接続は解放されます。
    FIXED_WAIT_SCHEME
    =2
    setMaxLimit() で設定した値以上接続しようとすると、 空くまで待たされますが、setCacheFixedWaitTimeout() を経過すると SQLException が返ります。
    FIXED_RETURN_NULL_SCHEME
    =3
    setMaxLimit() で設定した値以上接続しようとすると、 null が返ります。

    以下に2つの例をあげます。

    1. cjob.java
    2. cthread.java

    cjob.java は、 毎回1つずつ接続し現在のセッション情報を表示するものです。 セッションを kill しない場合は、毎回おなじプロセスが使われます。

    /*----------------------------------------------------------------------
      Function : test program of connection pooling
                   connect system/manager
      Usage    : java cjob D/FR/FW [oci8/oci/thin
                   D :DYNAMIC_SCHEME
                   FW:FIXED_WAIT_SCHEME
                   FR:FIXED_RETURN_NULL_SCHEME
      Oracle   : ozzy:ora92032 < -- > ora817
                 alter system kill session 'SID,SERIAL#'
      CLASSPATH : $ORACLE_HOME/jdbc/lib/classes12dms.jar
                  $ORACLE_HOME/jlib/jndi.jar
      ----------------------------------------------------------------------*/
    import java.sql.*;
    import java.io.*;
    import oracle.jdbc.*;
    import oracle.jdbc.pool.*;
    
    class cjob {
       static OracleConnectionCacheImpl ods;
       static String url_thin   = "jdbc:oracle:thin:@bach:1817:ora817";
       static String url_oci8   = "jdbc:oracle:oci8:@bach817.it.ns-sol.co.jp";
       static String url_oci    = "jdbc:oracle:oci:@bach817.it.ns-sol.co.jp";
       static String opt[]      = {"oci8","oci","thin",null};
       static String url_lst[]  = {url_oci8,url_oci,url_thin};
       static String arg0[]     = {"D","FW","FR",null};
       static String schme_name[] = {"DYNAMIC_SCHEME","FIXED_WAIT_SCHEME",
                                     "FIXED_RETURN_NULL_SCHEME"};
       static final int schme_val[]  =
                        {OracleConnectionCacheImpl.DYNAMIC_SCHEME,
                         OracleConnectionCacheImpl.FIXED_WAIT_SCHEME,
                         OracleConnectionCacheImpl.FIXED_RETURN_NULL_SCHEME};
       static String userName   = "system",
                     passwd     = "manager";
       static final int  MAX_CONN   = 5;
       static final int  MIN_CONN   = 1;
       static final int  MAX_LOOP   = 50;
       static final int  ARG_NON    = 0;         // input option 0
       static final int  ARG_SCHEME = 1;         // input option 1
       static final int  ARG_DRIVER = 2;         // input option 2
    
       static final long TIME_LONG  = 60L;       // 60 sec
       static final long TIME_MIDL  = 30L;       // 30 sec
       static final long TIME_SHORT = 1L;        // 1 sec
       static final long TIME_ZERO  = 0L;        // 0 sec
    
       static final int  DYNAMIC    = 0;         // DYNAMIC_SCHEME
       static final int  FIX_WAIT   = 1;         // FIXED_WAIT_SCHEME
       static final int  FIX_RETURN = 2;         // FIXED_RETURN_NULL_SCHEME
    
       static final int  UNKNOWN_SCHME  = 10;
       static final int  INVALID_ARGS   = 11;
    
       public static void main (String args []) throws
                  SQLException,javax.naming.NamingException {
         int            i=0;   // set default
         int            schme;
         con_job        obj ;
         String         url;
    
    // check input options    args[0]=D/FR/FW    args[1]=oci8/oci/thin
        if (args.length == 2) {
          for (i=0;;i++) {
            if (opt[i] == null)           usage(args,ARG_DRIVER);
            if (opt[i].equals(args[1]))   break;
          }
        } else if (args.length != 1)      usage(args,ARG_NON);
        url = url_lst[i];
    // check input options    args[0]=D/FR/FW
        for (schme=0; ; schme++)   {
            if (arg0[schme] == null)           usage(args,ARG_SCHEME);
            if (arg0[schme].equals(args[0]))   break;
        }
        System.out.println("url = "+url);
    //  System.out.println("getLoginTimeout = "+ods.getLoginTimeout());
    
        ods = new OracleConnectionCacheImpl();
        ods.setDriverType(opt[i]);
        ods.setURL(url);
        ods.setUser(userName);
        ods.setPassword(passwd);
    
    // Set the Max/Min Limit
        ods.setMaxLimit (MAX_CONN);
        ods.setMinLimit (MIN_CONN);
    
        ods.setCacheInactivityTimeout(TIME_LONG);
        ods.setCacheTimeToLiveTimeout(TIME_MIDL);
        ods.setCacheFixedWaitTimeout(TIME_SHORT);
        ods.setCacheFixedWaitIdleTime(TIME_SHORT);
        ods.setThreadWakeUpInterval(TIME_SHORT);
    // Set schme
        ods.setCacheScheme (schme_val[schme]);
    
        System.out.println("reference = "
                             +ods.getReference());
        System.out.print("CacheInactivityTimeout\t="
                             +ods.getCacheInactivityTimeout());
        System.out.println("\t:  CacheTimeToLiveTimeout\t="
                             +ods.getCacheTimeToLiveTimeout());
        System.out.print("CacheFixedWaitTimeout\t="
                             +ods.getCacheFixedWaitTimeout());
        System.out.println("\t:  CacheFixedWaitIdleTime\t="
                             +ods.getCacheFixedWaitIdleTime());
        System.out.println("ThreadWakeUpInterval\t="
                             +ods.getThreadWakeUpInterval());
    
        System.out.println("Cache Scheme\t\t="+schme_name[schme]);
        if (ods.getWarnings() != null)
            System.out.println(ods.getWarnings());
        System.out.println("---------------------------------------------------\n");
    
        obj = new con_job();
        for (i=0; i<MAX_LOOP; i++) {
           obj.job();
        }
        ods.close();
        System.exit(0);
      }
    
      static OracleConnectionCacheImpl getConn() {
         return ods;
      }
    
      static void usage(String args[],int no) {
        StringBuffer  option = new StringBuffer();
        String        use1 = "Usage : java cjob D/FR/FW [";
        String        use2 = "]   (default:oci8)";
        String        optstr ;
    
        for (int i=0; ; i++) {
          if (opt[i] == null)  break;
          option = option.append(opt[i]).append("/");
        }
        optstr = option.toString();
    
        if (args.length != 0)
           System.out.println("Error : invalid option : "+args[no-1]+"\n");
        else
           System.out.println("Error : must specify cache scheme\n");
    
        System.out.print(use1);
        System.out.print(optstr.substring(0,optstr.length()-1));
        System.out.println(use2);
        System.exit(INVALID_ARGS);
      }
    }
    
    class con_job {
       static final String QUERY_STR =
         "select s.sid, s.SERIAL#, s.PROGRAM, "
           + " to_char(s.LOGON_TIME,'hh24:mi:ss'), "
           + " s.STATUS, s.PROCESS, p.SPID, s.SERVER "
           + "from (select * from v$session where PROGRAM like 'JDBC%' "
           + "or PROGRAM like 'java%') s, v$process p "
           + "where s.paddr = p.addr(+) order by logon_time, p.pid";
       static final String HEADER =
    "SID  SERIAL#    PROGRAM                 TIME      STATUS      PROCESS  SPID\n--
    -  -------    ----------------------  --------- ---------   -------  ------";
    // 9       1637    java@ozzy (TNS V1-V3)   00:18:36  KILLED        20072   null
       static final String DO_EXIT = "quit";
    
       public void job() {
         String                    dum;
         Connection                conn;
         con_job                   own = new con_job();
         OracleConnectionCacheImpl ods2=cjob.getConn();
    
         System.out.println("New thread : Info = "+Thread.currentThread());
         try {
           conn = ods2.getConnection();
           chkconn (conn ,"Connection conns");
           own.query(conn);
           dum = own.inp_str("Opened]\t"+own.getActiveSize(ods2));
    
           conn.close();
           dum = own.inp_str("Closed]\t"+own.getActiveSize(ods2));
         } catch (Exception e) { e.printStackTrace();}
         return ;
       }
    
       void query(Connection conn) {
           Statement stmt;
           ResultSet rs;
    
         try {
           stmt = conn.createStatement ();
           rs   = stmt.executeQuery (QUERY_STR);
           System.out.println(HEADER);
           while(rs.next ())  {
             System.out.print(rs.getString (1)+"\t");    // SID
             System.out.print(rs.getString (2)+"\t");    // SERIAL#
             System.out.print(rs.getString (3)+"\t");    // PROGRAM
             System.out.print(rs.getString (4)+"  ");    // TIME
             System.out.print(rs.getString (5)+"\t");    // STATUS
             System.out.print(rs.getString (6)+"\t");    // PROCESS
             System.out.print(rs.getString (7)+"\n");    // SPID
    //       System.out.print(rs.getString (8)+"\n");    // SERVER
           }
         } catch (Exception e) { e.printStackTrace();}
       }
    
       String getActiveSize(OracleConnectionCacheImpl ods) {
         return (": Active size=" + ods.getActiveSize() +
                 ": Cache Size=" + ods.getCacheSize());
       }
    
       void chkconn(Connection con,String str) {
         if (con == null)
           System.out.println("It has been failed to connect ");
       }
    
       String inp_str(String cnst) {
          int          ch;
          StringBuffer str = new StringBuffer();
    
          System.out.println(cnst+"]\t"+ "  if OK, then RETURN");
          for (;;) {
             try {
                ch = (char) System.in.read();
                if (ch == '\n')   break;
                str.append((char) ch);
             }  catch (Exception e) { e.printStackTrace();}
          }
          if (str.toString().equals(DO_EXIT))   System.exit(0);
          return (str.toString());
       }
    }
    
    920txozzy-36 11:55am] java cjob D url = jdbc:oracle:oci8:@bach817.it.ns-sol.co.jp reference = Reference Class Name: oracle.jdbc.pool.OracleConnectionCacheImpl Type: url Content: jdbc:oracle:oci8:@bach817.it.ns-sol.co.jp Type: userName Content: system Type: passWord Content: manager Type: driverType Content: oci8 Type: networkProtocol Content: tcp Type: minLimit Content: 1 Type: maxLimit Content: 5 CacheInactivityTimeout =60 : CacheTimeToLiveTimeout =30 CacheFixedWaitTimeout =1 : CacheFixedWaitIdleTime =30 ThreadWakeUpInterval =1 Cache Scheme =DYNAMIC_SCHEME --------------------------------------------------- New thread : Info = Thread[main,5,main] SID SERIAL# PROGRAM TIME STATUS PROCESS SPID --- ------- ---------------------- --------- --------- ------- ------ 7 369 java@ozzy (TNS V1-V3) 12:40:35 ACTIVE 24597 5464 Opened] : Active size=1: Cache Size=1] if OK, then RETURN Closed] : Active size=0: Cache Size=1] if OK, then RETURN New thread : Info = Thread[main,5,main] SID SERIAL# PROGRAM TIME STATUS PROCESS SPID --- ------- ---------------------- --------- --------- ------- ------ 7 369 java@ozzy (TNS V1-V3) 12:40:35 ACTIVE 24597 5464 Opened] : Active size=1: Cache Size=1] if OK, then RETURN Closed] : Active size=0: Cache Size=1] if OK, then RETURN New thread : Info = Thread[main,5,main] SID SERIAL# PROGRAM TIME STATUS PROCESS SPID --- ------- ---------------------- --------- --------- ------- ------ 7 369 java@ozzy (TNS V1-V3) 12:40:35 ACTIVE 24597 5464 Opened] : Active size=1: Cache Size=1] if OK, then RETURN quit
    SQL> @sess SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 7 369 java@ozzy (TNS V1-V3) 12:40:35 12 INACTIVE 24597 5464 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 7 369 java@ozzy (TNS V1-V3) 12:40:35 6 INACTIVE 24597 5464 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 7 369 java@ozzy (TNS V1-V3) 12:40:35 6 INACTIVE 24597 5464 DEDICATED SQL> / レコードが選択されませんでした。

    cthread.java は、 毎回複数のスレッドで接続し現在のセッション情報を表示するものです。 セッションを kill しない場合は、毎回おなじプロセスが使われます。

    /*----------------------------------------------------------------------
      Function  : test program of connection pooling
                 connect system/manager
      Usage     : java cthread D/FR/FW [oci8/oci/thin]
                D :DYNAMIC_SCHEME   [pooling is dynamic, TimeToLiveTimeout..close
                FR:FIXED_RETURN_NULL_SCHEME  [pooling is fixed size if over null
                FW:FIXED_WAIT_SCHEME         [pooling is fixed size if over wait
      Oracle    : ozzy:ora92032 < -- > ora817
                 alter system kill session 'SID,SERIAL#';
      CLASSPATH : $ORACLE_HOME/jdbc/lib/classes12dms.jar
                  $ORACLE_HOME/jlib/jndi.jar
      ----------------------------------------------------------------------*/
    import java.sql.*;
    import java.io.*;
    import oracle.jdbc.*;
    import oracle.jdbc.pool.*;
    
    class cthread {
       static OracleConnectionCacheImpl ods= null;
       static final String url_thin   = "jdbc:oracle:thin:@bach:1817:ora817";
       static final String url_oci8   = "jdbc:oracle:oci8:@bach817.it.ns-sol.co.jp";
       static final String url_oci    = "jdbc:oracle:oci:@bach817.it.ns-sol.co.jp";
       static final String opt[]      = {"oci8","oci","thin",null};
       static final String url_lst[]  = {url_oci8,url_oci,url_thin};
       static final String arg0[]     = {"D","FW","FR",null};
       static final String schme_name[] = {"DYNAMIC_SCHEME","FIXED_WAIT_SCHEME",
                                     "FIXED_RETURN_NULL_SCHEME"};
       static final int schme_val[]  =
                        {OracleConnectionCacheImpl.DYNAMIC_SCHEME,
                         OracleConnectionCacheImpl.FIXED_WAIT_SCHEME,
                         OracleConnectionCacheImpl.FIXED_RETURN_NULL_SCHEME};
       static final String userName   = "system",
                           passwd     = "manager";
       static final int  MAX_CONN     = 5;
       static final int  MY_CONN      = 7;
       static final int  MIN_CONN     = 1;
       static final int  MAX_LOOP     = 50;
       static final int  ARG_NON      = 0;           // input option 0
       static final int  ARG_SCHEME   = 1;           // input option 1
       static final int  ARG_DRIVER   = 2;           // input option 2
    
       static final long TIME_INACTIVE  = 60L;       // 60 sec
       static final long TIME_TIMEOUT   = 30L;       // 30 sec
       static final long TIME_WAKE_INT  = 1L;        // 1 sec
       static final long TIME_SHORT     = 1L;        // 1 sec
       static final long TIME_ZERO      = 0L;        // 0 sec
    
       static final int  DYNAMIC    = 0;         // DYNAMIC_SCHEME
       static final int  FIX_WAIT   = 1;         // FIXED_WAIT_SCHEME
       static final int  FIX_RETURN = 2;         // FIXED_RETURN_NULL_SCHEME
    
       static final int  UNKNOWN_SCHME  = 10;
       static final int  INVALID_ARGS   = 11;
    
       public static void main (String args []) throws
                  SQLException,javax.naming.NamingException {
         int            i=0;   // set default
         int            schme,my_conn=MY_CONN;
         String         url;
         con_thread     obj[] = new con_thread[MY_CONN];
         cthread        own = new cthread();
         OracleConnectionCacheImpl  occ;
    
    // check input options
        if (args.length == 2) {
          for (i=0;;i++) {
            if (opt[i] == null)           usage(args,ARG_DRIVER);
            if (opt[i].equals(args[1]))   break;
          }
        } else if (args.length != 1)      usage(args,ARG_NON);
        url = url_lst[i];
    // check input options    args[0]=D/FR/FW
        for (schme=0; ; schme++)   {
            if (arg0[schme] == null)           usage(args,ARG_SCHEME);
            if (arg0[schme].equals(args[0]))   break;
        }
    
        System.out.println("url = "+url);
    //  System.out.println("getLoginTimeout = "+ods.getLoginTimeout());
    
        own.setOracleConnect();
        occ = own.getConn();
        occ.setDriverType(opt[i]);
        occ.setURL(url);
        occ.setUser(userName);
        occ.setPassword(passwd);
    
    // Set the Max/Min Limit
        occ.setMaxLimit (MAX_CONN);
        occ.setMinLimit (MIN_CONN);
    
        ods.setCacheInactivityTimeout(TIME_INACTIVE);
        ods.setCacheTimeToLiveTimeout(TIME_TIMEOUT);
        ods.setCacheFixedWaitTimeout(TIME_SHORT);
        ods.setCacheFixedWaitIdleTime(TIME_SHORT);
        ods.setThreadWakeUpInterval(TIME_WAKE_INT);
    
    // Set schme
        ods.setCacheScheme (schme_val[schme]);
    
    //  System.out.println("reference = " +occ.getReference());
        System.out.print("CacheInactivityTimeout\t="
                             +ods.getCacheInactivityTimeout());
        System.out.println("\t:  CacheTimeToLiveTimeout\t="
                             +ods.getCacheTimeToLiveTimeout());
        System.out.print("CacheFixedWaitTimeout\t="
                             +ods.getCacheFixedWaitTimeout());
        System.out.println("\t:  CacheFixedWaitIdleTime\t="
                             +ods.getCacheFixedWaitIdleTime());
        System.out.println("ThreadWakeUpInterval\t="
                             +ods.getThreadWakeUpInterval());
    
        System.out.println("Cache Scheme\t\t="+schme_name[schme]);
        if (ods.getWarnings() != null)
            System.out.println(ods.getWarnings());
        System.out.println("---------------------------------------------------\n");
    
        try {
           for (int k=0; k<MAX_LOOP; k++) {
              for (i=0; i<my_conn; i++) {
                 obj[i] = new con_thread();
                 obj[i].start();
              }
              for (i=0; i<my_conn; i++) {
                 obj[i].join();
              }
           }
        }  catch (Exception e) {e.printStackTrace();}
        occ.close();
        System.exit(0);
      }
    
      void setOracleConnect() {
         try {
            ods = new OracleConnectionCacheImpl();
         } catch (Exception e) { e.printStackTrace();}
      }
    
      OracleConnectionCacheImpl getConn() {
         if (ods != null)   return ods;
         else  {
            System.out.println("OracleConnectionCacheImpl is null!\n");
         }
         return null;
      }
    
      static void usage(String args[],int no) {
        StringBuffer  option = new StringBuffer();
        String        use1 = "Usage : java cthread D/FR/FW [";
        String        use2 = "]     (default:oci8)";
        String        optstr ;
    
        for (int i=0; ; i++) {
          if (opt[i] == null)  break;
          option = option.append(opt[i]).append("/");
        }
        optstr = option.toString();
    
        if (args.length != 0)
           System.out.println("Error : invalid option : "+args[no-1]+"\n");
        else
           System.out.println("Error : must specify cache scheme\n");
        System.out.print(use1);
        System.out.print(optstr.substring(0,optstr.length()-1));
        System.out.println(use2);
        System.exit(INVALID_ARGS);
      }
    }
    
    class con_thread extends Thread  {
       static final String QUERY_STR =
         "select s.sid, s.SERIAL#, s.PROGRAM, "
           + " to_char(s.LOGON_TIME,'hh24:mi:ss'), "
           + " s.STATUS, s.PROCESS, p.SPID, s.SERVER "
           + "from (select * from v$session where PROGRAM like 'JDBC%' "
           + "or PROGRAM like 'java%') s, v$process p "
           + "where s.paddr = p.addr(+) order by logon_time, p.pid";
       static final String HEADER =
    "SID  SERIAL#    PROGRAM                 TIME      STATUS      PROCESS  SPID\n--
    -  -------    ----------------------  --------- ---------   -------  ------";
    // 9       1637    java@ozzy (TNS V1-V3)   00:18:36  KILLED        20072   null
       static final String DO_EXIT = "quit";
       static final int TIME_SHORT = 1000;     // 1sec
    
       public void run() {
         cthread                   parent = new cthread();
         OracleConnectionCacheImpl ods2   = parent.getConn();
         Connection                conn;
    
         System.out.println("New thread : Info = "+Thread.currentThread());
         try {
           conn = ods2.getConnection();
           query(ods2,conn);
         } catch (Exception e) { e.printStackTrace();}
       }
    
       static synchronized void query(OracleConnectionCacheImpl ods,
                                      Connection conn) {
         String        dum;
         Statement     stmt;
         ResultSet     rs;
    
         if (conn == null)  {
            System.out.println("It has been failed to connect "+currentThread());
            return;
         }
    //   System.out.println("It has been succeeded to connect !");
    
         try {
           stmt = conn.createStatement ();
           sleep(TIME_SHORT);
           rs   = stmt.executeQuery (QUERY_STR);
           System.out.println(HEADER);
           while(rs.next ())  {
             System.out.print(rs.getString (1)+"\t");    // SID
             System.out.print(rs.getString (2)+"\t");    // SERIAL#
             System.out.print(rs.getString (3)+"\t");    // PROGRAM
             System.out.print(rs.getString (4)+"  ");    // TIME
             System.out.print(rs.getString (5)+"\t");    // STATUS
             System.out.print(rs.getString (6)+"\t");    // PROCESS
             System.out.print(rs.getString (7)+"\n");    // SPID
    //       System.out.print(rs.getString (8)+"\n");    // SERVER
           }
           System.out.println("Opened]\t"+getActiveSize(ods)+"  "+currentThread());
           dum = inp_str("Opened");
           conn.close();
           System.out.println("Closed]\t"+getActiveSize(ods)+"  "+currentThread());
           dum = inp_str("Closed");
    //   } catch (Exception e) { e.printStackTrace();return;}
         } catch (SQLException e) {
             System.out.println("Exception ORA-"+e.getErrorCode()+"  "+
                                 currentThread()+"\n");
         } catch (InterruptedException e) { return;}
         return ;
       }
    
       static String getActiveSize(OracleConnectionCacheImpl ods) {
         return ("Cache : Active size=" + ods.getActiveSize() +
                 ": Cache Size=" + ods.getCacheSize());
       }
    
       static synchronized String inp_str(String cnst) {
          int    ch;
          StringBuffer str = new StringBuffer();
    
          try  {
             System.out.println(cnst+"]\t"+currentThread()+ "  if OK, then RETURN");
             for (;;) {
                ch = (char) System.in.read();
                if (ch == '\n')   break;
                str.append((char) ch);
             }
             if (str.toString().equals(DO_EXIT))   System.exit(0);
          }  catch (Exception e) { e.printStackTrace();}
          return (str.toString());
       }
    }
    
    920txozzy-28 11:31am] java cthread D url = jdbc:oracle:oci8:@bach817.it.ns-sol.co.jp CacheInactivityTimeout =60 : CacheTimeToLiveTimeout =30 CacheFixedWaitTimeout =1 : CacheFixedWaitIdleTime =30 ThreadWakeUpInterval =1 Cache Scheme =DYNAMIC_SCHEME --------------------------------------------------- New thread : Info = Thread[Thread-2,5,main] New thread : Info = Thread[Thread-3,5,main] New thread : Info = Thread[Thread-4,5,main] New thread : Info = Thread[Thread-5,5,main] New thread : Info = Thread[Thread-6,5,main] New thread : Info = Thread[Thread-7,5,main] New thread : Info = Thread[Thread-8,5,main] SID SERIAL# PROGRAM TIME STATUS PROCESS SPID --- ------- ---------------------- --------- --------- ------- ------ 12 2007 java@ozzy (TNS V1-V3) 10:58:43 ACTIVE 13564 5356 13 389 java@ozzy (TNS V1-V3) 10:58:46 INACTIVE 13564 5358 14 326 java@ozzy (TNS V1-V3) 10:58:46 INACTIVE 13564 5360 7 327 java@ozzy (TNS V1-V3) 10:58:46 INACTIVE 13564 5362 9 638 java@ozzy (TNS V1-V3) 10:58:46 INACTIVE 13564 5364 8 442 java@ozzy (TNS V1-V3) 10:58:47 INACTIVE 13564 5366 11 396 java@ozzy (TNS V1-V3) 10:58:47 INACTIVE 13564 5368 Opened] Cache : Active size=7: Cache Size=7 Thread[Thread-2,5,main] Opened] Thread[Thread-2,5,main] if OK, then RETURN Closed] Cache : Active size=0: Cache Size=0 Thread[Thread-2,5,main] Closed] Thread[Thread-2,5,main] if OK, then RETURN Exception ORA-17073 Thread[Thread-3,5,main] Exception ORA-17073 Thread[Thread-4,5,main] Exception ORA-17073 Thread[Thread-5,5,main] Exception ORA-17073 Thread[Thread-6,5,main] Exception ORA-17073 Thread[Thread-7,5,main] Exception ORA-17073 Thread[Thread-8,5,main] New thread : Info = Thread[Thread-9,5,main] New thread : Info = Thread[Thread-11,5,main] New thread : Info = Thread[Thread-10,5,main] New thread : Info = Thread[Thread-12,5,main] New thread : Info = Thread[Thread-14,5,main] New thread : Info = Thread[Thread-15,5,main] New thread : Info = Thread[Thread-13,5,main] SID SERIAL# PROGRAM TIME STATUS PROCESS SPID --- ------- ---------------------- --------- --------- ------- ------ 8 444 java@ozzy (TNS V1-V3) 11:00:44 ACTIVE 13564 5388 11 405 java@ozzy (TNS V1-V3) 11:00:45 INACTIVE 13564 5390 9 646 java@ozzy (TNS V1-V3) 11:00:45 INACTIVE 13564 5392 13 397 java@ozzy (TNS V1-V3) 11:00:45 INACTIVE 13564 5394 12 2015 java@ozzy (TNS V1-V3) 11:00:45 INACTIVE 13564 5396 14 334 java@ozzy (TNS V1-V3) 11:00:45 INACTIVE 13564 5398 7 335 java@ozzy (TNS V1-V3) 11:00:45 INACTIVE 13564 5400 Opened] Cache : Active size=7: Cache Size=7 Thread[Thread-9,5,main] Opened] Thread[Thread-9,5,main] if OK, then RETURN quit
    SQL> @sess SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 8 444 java@ozzy (TNS V1-V3) 11:00:44 1 INACTIVE 13564 5388 DEDICATED 11 405 java@ozzy (TNS V1-V3) 11:00:45 1 INACTIVE 13564 5390 DEDICATED 9 646 java@ozzy (TNS V1-V3) 11:00:45 1 INACTIVE 13564 5392 DEDICATED 13 397 java@ozzy (TNS V1-V3) 11:00:45 1 INACTIVE 13564 5394 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:00:45 1 INACTIVE 13564 5396 DEDICATED 14 334 java@ozzy (TNS V1-V3) 11:00:45 1 INACTIVE 13564 5398 DEDICATED 7 335 java@ozzy (TNS V1-V3) 11:00:45 1 INACTIVE 13564 5400 DEDICATED 7行が選択されました。 SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 8 444 java@ozzy (TNS V1-V3) 11:00:44 10 INACTIVE 13564 5388 DEDICATED 11 405 java@ozzy (TNS V1-V3) 11:00:45 10 INACTIVE 13564 5390 DEDICATED 9 646 java@ozzy (TNS V1-V3) 11:00:45 10 INACTIVE 13564 5392 DEDICATED 13 397 java@ozzy (TNS V1-V3) 11:00:45 10 INACTIVE 13564 5394 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:00:45 10 INACTIVE 13564 5396 DEDICATED 14 334 java@ozzy (TNS V1-V3) 11:00:45 10 INACTIVE 13564 5398 DEDICATED 7 335 java@ozzy (TNS V1-V3) 11:00:45 10 INACTIVE 13564 5400 DEDICATED 7行が選択されました。 SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 646 java@ozzy (TNS V1-V3) 11:00:45 40 INACTIVE 13564 5392 DEDICATED 13 397 java@ozzy (TNS V1-V3) 11:00:45 40 INACTIVE 13564 5394 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:00:45 40 INACTIVE 13564 5396 DEDICATED 14 334 java@ozzy (TNS V1-V3) 11:00:45 40 INACTIVE 13564 5398 DEDICATED 7 335 java@ozzy (TNS V1-V3) 11:00:45 40 INACTIVE 13564 5400 DEDICATED SQL> !ps -efl|grep oracleora817 87:000 S ora817 5172 5171 0 69 0 - 13377 pipe_w 10:24 ? 00:00: 00 oracleora817 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq))) 88:000 S ora817 5392 1 0 69 0 - 13370 tcp_da 11:00 ? 00:00: 00 oracleora817 (DESCRIPTION=(LOCAL=NO)(SDU=4096)) 89:000 S ora817 5394 1 0 69 0 - 13370 tcp_da 11:00 ? 00:00: 00 oracleora817 (DESCRIPTION=(LOCAL=NO)(SDU=4096)) 90:000 S ora817 5396 1 0 69 0 - 13370 tcp_da 11:00 ? 00:00: 00 oracleora817 (DESCRIPTION=(LOCAL=NO)(SDU=4096)) 91:000 S ora817 5398 1 0 69 0 - 13370 tcp_da 11:00 ? 00:00: 00 oracleora817 (DESCRIPTION=(LOCAL=NO)(SDU=4096)) 92:000 S ora817 5400 1 0 69 0 - 13370 tcp_da 11:00 ? 00:00: 00 oracleora817 (DESCRIPTION=(LOCAL=NO)(SDU=4096)) 98:000 S ora817 5408 5171 15 70 0 - 961 rt_sig 11:01 pts/4 00:00: 00 -bin/tcsh -c ps -efl|grep oracleora817 100:000 S ora817 5423 5408 0 70 0 - 632 pipe_w 11:01 pts/4 00:00 :00 grep -n oracleora817 SQL> @sess SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 646 java@ozzy (TNS V1-V3) 11:00:45 61 INACTIVE 13564 5392 DEDICATED 13 397 java@ozzy (TNS V1-V3) 11:00:45 61 INACTIVE 13564 5394 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:00:45 61 INACTIVE 13564 5396 DEDICATED 14 334 java@ozzy (TNS V1-V3) 11:00:45 61 INACTIVE 13564 5398 DEDICATED 7 335 java@ozzy (TNS V1-V3) 11:00:45 61 INACTIVE 13564 5400 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 646 java@ozzy (TNS V1-V3) 11:00:45 86 INACTIVE 13564 5392 DEDICATED 13 397 java@ozzy (TNS V1-V3) 11:00:45 86 INACTIVE 13564 5394 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:00:45 86 INACTIVE 13564 5396 DEDICATED 14 334 java@ozzy (TNS V1-V3) 11:00:45 86 INACTIVE 13564 5398 DEDICATED 7 335 java@ozzy (TNS V1-V3) 11:00:45 86 INACTIVE 13564 5400 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 646 java@ozzy (TNS V1-V3) 11:00:45 92 INACTIVE 13564 5392 DEDICATED SQL> / レコードが選択されませんでした。
    920txozzy-30 11:40am] java cthread FW url = jdbc:oracle:oci8:@bach817.it.ns-sol.co.jp CacheInactivityTimeout =60 : CacheTimeToLiveTimeout =30 CacheFixedWaitTimeout =1 : CacheFixedWaitIdleTime =30 ThreadWakeUpInterval =1 Cache Scheme =FIXED_WAIT_SCHEME --------------------------------------------------- New thread : Info = Thread[Thread-2,5,main] New thread : Info = Thread[Thread-3,5,main] New thread : Info = Thread[Thread-4,5,main] New thread : Info = Thread[Thread-5,5,main] New thread : Info = Thread[Thread-6,5,main] New thread : Info = Thread[Thread-7,5,main] New thread : Info = Thread[Thread-8,5,main] SID SERIAL# PROGRAM TIME STATUS PROCESS SPID --- ------- ---------------------- --------- --------- ------- ------ 9 649 java@ozzy (TNS V1-V3) 11:07:08 ACTIVE 13596 5425 14 342 java@ozzy (TNS V1-V3) 11:07:11 INACTIVE 13596 5427 13 405 java@ozzy (TNS V1-V3) 11:07:11 INACTIVE 13596 5429 12 2023 java@ozzy (TNS V1-V3) 11:07:11 INACTIVE 13596 5431 7 343 java@ozzy (TNS V1-V3) 11:07:11 INACTIVE 13596 5433 java.sql.SQLException: Fixed Wait timeout elapsed at java.lang.Throwable.fillInStackTrace(Native Method) at java.lang.Throwable.fillInStackTrace(Compiled Code) at java.lang.Throwable.(Compiled Code) at java.lang.Exception.(Compiled Code) at java.sql.SQLException.(SQLException.java:43) at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134) at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179) at oracle.jdbc.dbaccess.DBError.throwSqlException(Compiled Code) at oracle.jdbc.pool.OracleConnectionCacheImpl.getPooledConnection(Compil ed Code) at oracle.jdbc.pool.OracleConnectionCacheImpl.getConnection(OracleConnec tionCacheImpl.java:298) at oracle.jdbc.pool.OracleConnectionCacheImpl.getConnection(OracleConnec tionCacheImpl.java:268) at con_thread.run(cthread.java:191) java.sql.SQLException: Fixed Wait timeout elapsed at java.lang.Throwable.fillInStackTrace(Native Method) at java.lang.Throwable.fillInStackTrace(Compiled Code) at java.lang.Throwable.(Compiled Code) at java.lang.Exception.(Compiled Code) at java.sql.SQLException.(SQLException.java:43) at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134) at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179) at oracle.jdbc.dbaccess.DBError.throwSqlException(Compiled Code) at oracle.jdbc.pool.OracleConnectionCacheImpl.getPooledConnection(Compil ed Code) at oracle.jdbc.pool.OracleConnectionCacheImpl.getConnection(OracleConnec tionCacheImpl.java:298) at oracle.jdbc.pool.OracleConnectionCacheImpl.getConnection(OracleConnec tionCacheImpl.java:268) at con_thread.run(cthread.java:191) Opened] Cache : Active size=5: Cache Size=5 Thread[Thread-2,5,main] Opened] Thread[Thread-2,5,main] if OK, then RETURN
    SQL> @sess SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 649 java@ozzy (TNS V1-V3) 11:07:08 3 INACTIVE 13596 5425 DEDICATED 14 342 java@ozzy (TNS V1-V3) 11:07:11 3 INACTIVE 13596 5427 DEDICATED 13 405 java@ozzy (TNS V1-V3) 11:07:11 3 INACTIVE 13596 5429 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:07:11 3 INACTIVE 13596 5431 DEDICATED 7 343 java@ozzy (TNS V1-V3) 11:07:11 3 INACTIVE 13596 5433 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 649 java@ozzy (TNS V1-V3) 11:07:08 21 INACTIVE 13596 5425 DEDICATED 14 342 java@ozzy (TNS V1-V3) 11:07:11 21 INACTIVE 13596 5427 DEDICATED 13 405 java@ozzy (TNS V1-V3) 11:07:11 21 INACTIVE 13596 5429 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:07:11 21 INACTIVE 13596 5431 DEDICATED 7 343 java@ozzy (TNS V1-V3) 11:07:11 21 INACTIVE 13596 5433 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 649 java@ozzy (TNS V1-V3) 11:07:08 30 INACTIVE 13596 5425 DEDICATED 14 342 java@ozzy (TNS V1-V3) 11:07:11 30 INACTIVE 13596 5427 DEDICATED 13 405 java@ozzy (TNS V1-V3) 11:07:11 30 INACTIVE 13596 5429 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:07:11 30 INACTIVE 13596 5431 DEDICATED 7 343 java@ozzy (TNS V1-V3) 11:07:11 30 INACTIVE 13596 5433 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 649 java@ozzy (TNS V1-V3) 11:07:08 36 INACTIVE 13596 5425 DEDICATED 14 342 java@ozzy (TNS V1-V3) 11:07:11 36 INACTIVE 13596 5427 DEDICATED 13 405 java@ozzy (TNS V1-V3) 11:07:11 36 INACTIVE 13596 5429 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:07:11 36 INACTIVE 13596 5431 DEDICATED 7 343 java@ozzy (TNS V1-V3) 11:07:11 36 INACTIVE 13596 5433 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 649 java@ozzy (TNS V1-V3) 11:07:08 48 INACTIVE 13596 5425 DEDICATED 14 342 java@ozzy (TNS V1-V3) 11:07:11 48 INACTIVE 13596 5427 DEDICATED 13 405 java@ozzy (TNS V1-V3) 11:07:11 48 INACTIVE 13596 5429 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:07:11 48 INACTIVE 13596 5431 DEDICATED 7 343 java@ozzy (TNS V1-V3) 11:07:11 48 INACTIVE 13596 5433 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 649 java@ozzy (TNS V1-V3) 11:07:08 55 INACTIVE 13596 5425 DEDICATED 14 342 java@ozzy (TNS V1-V3) 11:07:11 55 INACTIVE 13596 5427 DEDICATED 13 405 java@ozzy (TNS V1-V3) 11:07:11 55 INACTIVE 13596 5429 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:07:11 55 INACTIVE 13596 5431 DEDICATED 7 343 java@ozzy (TNS V1-V3) 11:07:11 55 INACTIVE 13596 5433 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 649 java@ozzy (TNS V1-V3) 11:07:08 76 INACTIVE 13596 5425 DEDICATED 14 342 java@ozzy (TNS V1-V3) 11:07:11 76 INACTIVE 13596 5427 DEDICATED 13 405 java@ozzy (TNS V1-V3) 11:07:11 76 INACTIVE 13596 5429 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:07:11 76 INACTIVE 13596 5431 DEDICATED 7 343 java@ozzy (TNS V1-V3) 11:07:11 76 INACTIVE 13596 5433 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 649 java@ozzy (TNS V1-V3) 11:07:08 111 INACTIVE 13596 5425 DEDICATED 14 342 java@ozzy (TNS V1-V3) 11:07:11 111 INACTIVE 13596 5427 DEDICATED 13 405 java@ozzy (TNS V1-V3) 11:07:11 111 INACTIVE 13596 5429 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:07:11 111 INACTIVE 13596 5431 DEDICATED 7 343 java@ozzy (TNS V1-V3) 11:07:11 111 INACTIVE 13596 5433 DEDICATED SQL> / SID NO PROGRAM START ETIM STATUS PROCE SPID SERVER ---- ---- --------------------- -------- ----- -------- ----- ----- ---------- 9 649 java@ozzy (TNS V1-V3) 11:07:08 117 INACTIVE 13596 5425 DEDICATED 14 342 java@ozzy (TNS V1-V3) 11:07:11 117 INACTIVE 13596 5427 DEDICATED 13 405 java@ozzy (TNS V1-V3) 11:07:11 117 INACTIVE 13596 5429 DEDICATED 12 #### java@ozzy (TNS V1-V3) 11:07:11 117 INACTIVE 13596 5431 DEDICATED 7 343 java@ozzy (TNS V1-V3) 11:07:11 117 INACTIVE 13596 5433 DEDICATED SQL> / レコードが選択されませんでした。

  5. JDBC でのログの取得方法
  6. oracle jdbc の動作確認のために、ログを取得したい場合があります。 以下にその方法を記述します。

    ログのレベルは、1から3で大きくなるほど詳細な情報が出ます。

    import java.io.*;
    import oracle.jdbc.driver.*;
    
    static int final LEVEL = 2;    // 1:low 2:middle 3:high
    
      OracleLog.setLogWriter(new PrintWriter(System.out));
      OracleLog.setLogVolume(LEVEL);
    

    尚、接続が完了してから使ってください。 接続時、ログ取得部分にバグがあり、以下のメッセージで異常終了する場合があります。 jdbc 9.2.0.5.0 より修正されています。(KROWN 72682)

    java.lang.NullPointerException
            at oracle.jdbc.dbaccess.DBError.addSqlWarning(DBError.java:801)
    

    また、以下のメッセージが出た場合は、CLASSPATH に XXX_g.jar を前に追加します。

    Oracle Jdbc tracing is not avaliable in a non-debug zip/jar file
    

  7. JDBC での様々な接続の仕方
  8. host=ozzy port=1581 ORACLE_SID=ora920tx を仮定します。

    [ thin MTS 接続 ] 
    jdbc:oracle:thin:@
        (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(host=ozzy)(port=1581))
        (CONNECT_DATA = (SID = ora920tx)(SERVER = shared)))
    
    [ thin 専用サーバ接続 ] 
    jdbc:oracle:thin:@
        (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(host=ozzy)(port=1581))
        (CONNECT_DATA = (SID = ora920tx)(SERVER = dedicated)))
    

  9. BLOB の例
  10. 次の操作を行うプログラム例を示します。

    1. BLOB を含む表にデータを格納する。
    2. BLOB を含む表からデータを取得する。

    BLOB を含む表にデータを格納する。

    /*
    SQL> desc blob_tbl;
     名前                                      NULL?    型
     ----------------------------------------- -------- ----------------------------
     ID                                        NOT NULL NUMBER(4)
     NAME                                               VARCHAR2(20)
     IMG                                                BLOB
    */
    import java.io.*;
    import java.sql.*;
    import oracle.jdbc.driver.*;
    import oracle.sql.*;
    
    class Blob1 {
       static final String ins = "insert into blob_tbl values(?,?,empty_blob())",
                           sel       = "Select img from blob_tbl where id =",
                           dbuser    = "taka",
                           dbpass    = "taka",
                           constring = "jdbc:oracle:thin:@ozzy:1530:ora817",
                           name      = "owl.jpg",
                           imgdata   = "JPG/owl.jpg";
    
       public static void main(String[] args) {
         int    id = 10;
    
         try {
           Class c = Class.forName("oracle.jdbc.driver.OracleDriver");
           Connection conn = DriverManager.getConnection(constring,dbuser,dbpass);
           conn.setAutoCommit(false);
    
         // 1  BLOBエントリを表内に作成
           OraclePreparedStatement ps = (OraclePreparedStatement)
                                          conn.prepareStatement(ins);
           ps.setInt(1,id);
           ps.setString(2,name);
           ps.execute();
           conn.commit();
           ps.close();
    
         // 2  表からBLOBロケータを取得
           Statement stmt = conn.createStatement();
           ResultSet rset = stmt.executeQuery(sel + id + " for update");
           rset.next();
           BLOB bdata = ((OracleResultSet)rset).getBLOB(1);
    
         // 3  ファイル・ハンドラを宣言し、ストリームを作成
           File binaryFile = new File(imgdata);
           System.out.println(imgdata + " length = " + binaryFile.length());
           FileInputStream instream  = new FileInputStream(binaryFile);
           OutputStream    outstream = bdata.getBinaryOutputStream();
    
         // 4  BLOBに書き込むための理想的なチャンク・サイズを決定しバイト配列の作成
           int chunk = bdata.getChunkSize();
           byte[] buffer = new byte[chunk];
           int length = -1;
    
         // 5  ストリームを使用してBLOBに書き込み
           while ((length = instream.read(buffer)) != -1) {
             outstream.write(buffer,0,length);
           }
           instream.close();
           outstream.close();
           conn.commit();
           rset.close();
           stmt.close();
           conn.close();
           System.out.println("Insertion successed.");
         }
         catch(Exception e1){
           e1.printStackTrace();
         }
       }
    }
    

    BLOB を含む表からデータを取得する。

    import java.io.*;
    import java.sql.*;
    import oracle.jdbc.driver.*;
    import oracle.sql.*;
    
    class Blob2 {
       static final String sel       = "select name,img from blob_tbl where id =",
                           dbuser    = "taka",
                           dbpass    = "taka",
                           constring = "jdbc:oracle:thin:@ozzy:1530:ora817";
    
       public static void main(String[] args) {
         int id = 10;
    
         try {
           Class      c    = Class.forName("oracle.jdbc.driver.OracleDriver");
           Connection conn = DriverManager.getConnection(constring,dbuser,dbpass);
           Statement  stmt = conn.createStatement();
    
           // 設定したidのBLOBデータを取得する
           ResultSet rset = stmt.executeQuery(sel + id);
           rset.next();
    
           String name    = rset.getString(1);
           BLOB   bdata   = ((OracleResultSet)rset).getBLOB(2);
           long   length2 = bdata.length();
    
           // 取得したBLOBデータより、ディレクトリに取得した名前でファイル作成
           FileOutputStream foutstream = new FileOutputStream("OUT/" + name,false);
           InputStream      instream   = bdata.getBinaryStream();
           int chunk = bdata.getChunkSize();
           byte[] buffer = new byte[chunk];
           int length = -1;
           while ((length = instream.read(buffer)) != -1) {
             foutstream.write(buffer,0,length);
           }
    
           foutstream.flush();
           instream.close();
           foutstream.close();
           rset.close();
           stmt.close();
           conn.close();
         }
         catch(Exception e1) {
           e1.printStackTrace();
         }
       }
    }
    

  11. java から PL/SQL パッケージを使う例
  12. /*
     * This sample shows how to call a PL/SQL function that opens
     * a cursor and get the cursor back as a Java ResultSet.
     *
     * sqlType CURSOR corresponds to "ref cursor". open the cursor
     * by specifying CURSOR type at register method. retrieve the
     * value by getObject method.
     *
     * note: jdk1.2 is recommanded. jdk1.1 will also work
     */
    
    import java.sql.*;
    import java.io.*;
    
    // Importing the Oracle Jdbc driver package makes the code more readable
    import oracle.jdbc.*;
    
    class RefCur {
       static final String url = "jdbc:oracle:thin:@dio:1556:ora92032",
       user = "taka2",
       pass = "taka2",
       def1="create or replace package java_refcursor as ",
       def2=" type myrctype is ref cursor return EMP%ROWTYPE; " ,
       def3=" function job_listing (j varchar2, k varchar2) return myrctype; " ,
       def4="end java_refcursor;",
       bdy1="create or replace package body java_refcursor as " ,
       bdy2= " function job_listing (j varchar2, k varchar2) return myrctype is " ,
       bdy3= "   rc myrctype; " ,
       bdy4= " begin " ,
       bdy5= "   open rc for select * from emp where job = j or job = k;" ,
       bdy6= "   return rc; " ,
       bdy7= "  end; " ,
       bdy8= "end java_refcursor;";
    
      public static void main (String args [])
           throws SQLException {
        // Load the driver
        DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
    
        // Connect to the database
        Connection conn =
          DriverManager.getConnection (url,user,pass);
    
        // Create the stored procedure
        init (conn);
    
        // Prepare a PL/SQL call
        CallableStatement call =
          conn.prepareCall ("{ ? = call java_refcursor.job_listing (?, ?)}");
    
        // Find out all the SALES person
        //  (marketing representative and marketing manager)
        call.registerOutParameter (1, OracleTypes.CURSOR);
        call.setString (2, "SALESMAN");
        call.setString (3, "ANALYST");
        call.execute ();
        ResultSet rset = (ResultSet)call.getObject (1);
    
        // Dump the cursor
        while (rset.next ())
          System.out.println (rset.getString ("ENAME") + "  "
                              + rset.getString ("ENAME") + "  "
                              + rset.getString ("JOB"));
    
    
        // Close all the resources
        rset.close();
        call.close();
        conn.close();
    
      }
    
      // Utility function to create the stored procedure
      static void init (Connection conn)
           throws SQLException {
        Statement stmt = conn.createStatement ();
        String pkg_def=def1 + def2 + def3 + def4;
        String pkg_bdy=bdy1+bdy2+bdy3+bdy4+bdy5+bdy6+bdy7+bdy8;
    
        try {
          stmt.execute (pkg_def);
          stmt.execute (pkg_bdy);
        } catch (Exception e) {
           e.printStackTrace();
        }
    
        stmt.close();
      }
    }
    

  13. JDBC のいろいろな使い方
  14. $HOME/java/jar/tydbpj2/samples にいろいろなサンプルを入れました。
    実行する場合は、以下の表の java クラスが利用できます。

    クラス名 項     目 使用するクラス
    java.sql
    oracle.jdbc.driver
    Connect 接続のテスト Properties
    NoParameter パラメータなしの SQL 文の実行 executeUpdate
    InParameter IN パラメータありの SQL 文の実行 prepareStatement
    OutParameter OUT パラメータありの SQL 文の実行 prepareCall
    PLSQL PLSQL execute
    PLSQL2 PLSQL2 prepareCall
    StoredProgram ストアド・プロシージャ prepareCall
    RefCursor カーソル変数 prepareCall
    RefCursor2 カーソル変数 2 prepareCall
    DefineColumnType 列の型指定 executeQuery.
    UpdateByRowid ROWID での更新と自動コミット executeUpdate
    ExecuteBatch 更新のバッチ処理 OraclePreparedStatement.
    getExecuteBatch
    RowPrefetch 行のプリ・フェッチ OracleConnection.
    getDefaultRowfetch
    Stream ストリーム処理 OracleStatement.
    defineColumnType

    これらは、$HOME/java/jar の下に入っていますので、 以下のように実行します。

    > cd $HOME/java/jar
    > java tydbpj2.samples.Connect
    
    oracle.jdbc.driver.OracleConnection@XXXXX
    

    上記のメッセージが表示されれば、接続は成功です。

    ソースは、$HOME/java/jar/tydbpj2/samples と $HOME/java/jar/tydbpj2/util にあります。

    1. Connect.java
    2. package tydbpj2.samples;
      import java.sql.Connection;
      import java.util.Properties;
      import tydbpj2.util.DBInfo;
      
      public class Connect extends Register {
      
        protected Connection connection;
      
        public Connect () {
          try {
            // ユーザ名とパスワードのプロパティを設定する
            Properties p = new Properties();
            p.put("user", DBInfo.USERNAME);
            p.put("password", DBInfo.PASSWORD);
      
            // 特定のJDBC URLに接続する
            connection = driver.connect(DBInfo.CONNECTION_URL, p);
          } catch (Exception ex) {
            ex.printStackTrace();
          }
        }
      
        public static void main (String args[]) {
          Connect me = new Connect();
          System.out.println(me.connection);
          try {
            System.in.read();
          } catch (Exception ex) {}
        }
      }
      

    3. DBInfo.java
    4. package tydbpj2.util;
      
      public class DBInfo {
      
        private static final Resources resources =
          new Resources("tydbpj2.util.resources.dbinfo");
          
        public static final String DRIVER =
          resources.getString("driver");
      
        public static final String CONNECTION_URL =
          resources.getString("connectionURL");
      
        public static final String USERNAME =
          resources.getString("username");
      
        public static final String PASSWORD =
          resources.getString("password");
      
        private DBInfo() {}
      }
      

    5. Resources.java
    6. package tydbpj2.util;
      
      import java.util.MissingResourceException;
      import java.util.ResourceBundle;
      
      public class Resources {
      
        private ResourceBundle resources;
      
        public Resources(String baseName) {
          try {
            resources = ResourceBundle.getBundle(baseName);
          } catch (MissingResourceException ex) {
            ex.printStackTrace();
            resources = null;
          }
        }
      
        public String getString(String key) {
          if (resources == null) {
            return key;
          }
      
          try {
            return resources.getString(key);
          } catch (MissingResourceException ex) {
            return key;
          }
        }
      }
      

    7. Register.java
    8. package tydbpj2.samples;
      
      import java.sql.Driver;
      import tydbpj2.util.DBInfo;
      
      public class Register {
      
        protected Driver driver;
      
        public Register() {
          try {
            driver = (Driver)
              Class.forName(DBInfo.DRIVER).newInstance();
            //Driver のインスタンスを作成したときに、
            //DriverManager への登録が行われているので
            //registerDriver を実行すると二重に登録される
            //DriverManager.registerDriver(driver);
          } catch(Exception ex) {
            ex.printStackTrace();
          }
        }
      
        public static void main (String args[]) {
          Register me = new Register();
          System.out.println(me.driver);
          try {
            System.in.read();
          } catch (Exception ex) {}
        }
      }
      

    9. tydbpj2/util/resources/dbinfo.properties
    10. driver   = oracle.jdbc.driver.OracleDriver
      connectionURL = jdbc:oracle:oci8:@
      username = scott
      password = tiger
      

      説明 上記プログラムについて簡単に説明します。

      ResourceBundle には、環境に固有のオブジェクトが含まれます。 プログラムで String などの環境に固有のリソースが必要なときは、 ユーザの環境に合ったリソースバンドルからロードできます。 このように、リソースバンドルから、環境に固有の情報を切り離すことで、 ユーザの環境に依存しないプログラムを書けます。

      そのために Resources.java があり、 これで環境に固有のリソースを、ResourceBundle.getBundle で tydbpj2/util/resources/dbinfo.properties から読みます。

      ResourceBundle.getString(key) で key に対応する文字列を返します。 従って、DBInfo で接続に必要なキーを各変数に設定します。 DBInfo には、driver/connectionURL/username/password が環境に固有の情報として設定されていますので、実行時にその値を取得できます。

      p.put("user",DBInfo.USERNAME) では、DBInfo.USERNAME は、 resources.getString("username") から得られます。 それを Properties のハッシュテーブルにキー user で格納します。

      Connect.java は、データベースに接続します。
      まず Connect の main で Connect のコンストラクタを呼びます。 Connect は Register を拡張したクラスなので、 Register.java のコンストラクタ Register が呼ばれます。 ここで、Oracle ドライバがロードされます。

      データベースに接続するために java.util.Properties を使います。 Properties は、ストリームに保管したり、そこからロードしたりできます。 プロパティリストのそれぞれのキーとそれに対応する値は文字列です。

      DriverManager.getConnection(URL,Properties) で、データベースに接続します。 この場合、Properties に user と password キーに対応する値が設定されている必要があります。

  15. JDBC 固有の oracle エラー一覧
  16. jdbc 固有のエラーは、 17000 番代です。 エラー文は文字化けするバグが登録されています。

    エラー番号 内          容
    ORA-17001 内部エラー
    ORA-17002 I/O例外です。
    ORA-17003 列索引が無効です。
    ORA-17004 列の型が無効です。
    ORA-17005 サポートされない列の型です。
    ORA-17006 列名が無効です。
    ORA-17007 動的列が無効です。
    ORA-17008 非公開の接続です。
    ORA-17009 非公開の文です。
    ORA-17010 非公開の結果セットです。
    ORA-17011 空の結果セットです。
    ORA-17012 パラメータの型が競合します。
    ORA-17014 ResultSet.nextはコールされませんでした。
    ORA-17015 文は取り消されました。
    ORA-17016 文は時間切れになりました。
    ORA-17017 カーソルはすでに初期化済です。
    ORA-17018 無効なカーソルです。
    ORA-17019 1つの問合せのみ記述できます。
    ORA-17020 行のプリフェッチが無効です。
    ORA-17021 定義がありません。
    ORA-17022 索引に定義がありません。
    ORA-17023 サポートされない機能です。
    ORA-17024 読み込むデータがありません。
    ORA-17025 defines.isNull()でエラーが発生しました。
    ORA-17026 数値のオーバーフローです。
    ORA-17027 ストリームはすでにクローズ済です。
    ORA-17028 現行の結果セットがクローズされるまで、新規結果セットを実行できません。
    ORA-17029 setReadOnly:読込み専用の接続はサポートされません。
    ORA-17030 READ_COMMITTEDおよびSERIALIZABLEのみが有効なトランザクション・レベルです。
    ORA-17031 setAutoClose:自動クローズ・モードが「オン」の場合のみサポートされます。
    ORA-17032 行のプリフェッチをゼロに設定できません。
    ORA-17033 不完全なSQL92文字列です-位置
    ORA-17034 サポートされないSQL92トークンです-位置
    ORA-17035 サポートされないキャラクタ・セットです。
    ORA-17036 OracleNumberで例外が発生しました。
    ORA-17037 UTF8とUCS2との間の変換に失敗しました。
    ORA-17038 バイト配列の長さが不十分です。
    ORA-17039 文字配列の長さが不十分です。
    ORA-17040 接続URLにサブ・プロトコルの指定が必要です。
    ORA-17041 INまたはOUTパラメータがありません-索引:
    ORA-17042 バッチの値が無効です。
    ORA-17043 ストリームの最大サイズが無効です。
    ORA-17044 内部エラー:データ配列を割当てできません。
    ORA-17045 内部エラー:バッチの値範囲を超えてバインド変数にアクセスしようとしました。
    ORA-17046 内部エラー:データ・アクセスに対する索引が無効です。
    ORA-17047 型記述子の解析でエラーが発生しました。
    ORA-17048 型が定義されていません。
    ORA-17049 JAVAとSQLのオブジェクト型が適合しません。
    ORA-17050 ベクトルにそのような要素はありません。
    ORA-17051 このAPIは、UDT以外の型に使用できません。
    ORA-17052 この参照は有効ではありません。
    ORA-17053 サイズが無効です。
    ORA-17054 LOBロケータが無効です。
    ORA-17055 無効なキャラクタが見つかりました-
    ORA-17056 サポートされないキャラクタ・セットです。
    ORA-17057 非公開のLOBです。
    ORA-17058 内部エラー:NLS変換率が無効です。
    ORA-17059 内部表現の変換に失敗しました。
    ORA-17060 記述子の構成に失敗しました。
    ORA-17061 記述子がありません。
    ORA-17062 参照カーソルが無効です。
    ORA-17063 トランザクション中ではありません。
    ORA-17064 構文が無効、またはデータベース名がNULLです。
    ORA-17065 変換クラスがNULLです。
    ORA-17066 アクセス・レイヤーには固有の実装が必要です。
    ORA-17067 無効なOracleURLが指定されました。
    ORA-17068 コールに無効な引数があります。
    ORA-17069 明示的なXAコールを使用してください。
    ORA-17070 データ・サイズがこの型の最大サイズを超えています。
    ORA-17071 最大VARRAY制限を超えました。
    ORA-17072 列に対して挿入値が大きすぎます。
    ORA-17073 論理ハンドルはすでに無効です。
    ORA-17074 名前パターンが無効です。
    ORA-17075 転送専用の結果セットに対する操作が無効です。
    ORA-17076 読込み専用の結果セットに対する操作が無効です。
    ORA-17077 REF値の設定に失敗しました。
    ORA-17078 接続はすでにオープンしているため、操作できません。
    ORA-17079 既存のユーザー資格証明と一致しません。
    ORA-17080 無効なバッチ・コマンドです。
    ORA-17081 バッチ処理でエラーが発生しました。
    ORA-17082 カレント行がありません。
    ORA-17083 挿入行ではありません。
    ORA-17084 挿入行でコールされました。
    ORA-17085 値の競合が発生しました。
    ORA-17086 挿入行の列値が未定義です。
    ORA-17087 パフォーマンス・ヒントが無視されました:setFetchDirection()
    ORA-17088 要求した結果セットの型と同時実行レベルの構文はサポートされていません。
    ORA-17089 内部エラー
    ORA-17090 操作できません。
    ORA-17091 要求した型および/または同時実行レベルで結果セットを作成できません。
    ORA-17092 JDBC文でコール処理の終了を作成または実行できません。
    ORA-17093 OCI操作でOCI_SUCCESS_WITH_INFOが戻りました。
    ORA-17094 オブジェクト・タイプのバージョンが適合しません。
    ORA-17095 文のキャッシュするにはこの接続オブジェクトは使用できません。
    ORA-17096 文のキャッシュはこの論理接続に対して使用可能ではありません。
    ORA-17097 PL/SQLの索引表の要素タイプが無効です。
    ORA-17098 空のLOB操作は無効です。
    ORA-17099 PL/SQLの索引表の配列の長さが無効です。
    TTC メッセージ
    ORA-17401 プロトコル違反です。
    ORA-17402 RPAメッセージは1つのはずです。
    ORA-17403 RXHメッセージは1つのはずです。
    ORA-17404 予定より多いRXDを受け取りました。
    ORA-17405 UACの長さはゼロではありません。
    ORA-17406 最大バッファ長を超えています。
    ORA-17407 型表現が無効です(setRep)。
    ORA-17408 型表現が無効です(getRep)。
    ORA-17409 バッファ長が無効です。
    ORA-17410 ソケットから読み込むデータはこれ以上ありません。
    ORA-17411 データ型の表現が適合しません。
    ORA-17412 型の長さが最大を超えています。
    ORA-17413 キー・サイズが大きすぎます。
    ORA-17414 列名を保存するにはバッファ・サイズが不十分です。
    ORA-17415 この型は未処理です。
    ORA-17416 FATAL
    ORA-17417 NLSの問題で、列名のデコードに失敗しました。
    ORA-17418 内部構造体のフィールド長エラーです。
    ORA-17419 無効な列の数が戻りました。
    ORA-17420 Oracleバージョンが定義されていません。
    ORA-17421 型または接続が定義されていません。
    ORA-17422 ファクトリに無効なクラスがあります。
    ORA-17423 IOVの定義なしでPLSQLブロックを使用しています。
    ORA-17424 異なる配列操作を試みています。
    ORA-17425 PLSQLブロックでストリームを戻しています。
    ORA-17426 INバインド、OUTバインドともにNULLです。
    ORA-17427 初期化されていないOACを使用しています。
    ORA-17428 接続の後にはログオンのコールが必要です。
    ORA-17429 少なくともサーバーに接続している必要があります。
    ORA-17430 サーバーへのログオンが必要です。
    ORA-17431 解析するSQL文がNULLです。
    ORA-17432 all7でオプションが無効です。
    ORA-17433 コールの引数が無効です。
    ORA-17434 ストリーム・モードではありません。
    ORA-17435 IOVでin_out_bindsの数が無効です。
    ORA-17436 アウトバインドの数が無効です。
    ORA-17437 PLSQLブロックのIN/OUT引数にエラーがあります。
    ORA-17438 内部-予期しない値です。
    ORA-17439 SQLの型が無効です。
    ORA-17440 DBItem/DBTypeがNULLです。
    ORA-17441 このOracleバージョンはサポートされません。7.2.3以降はサポートされます。
    ORA-17442 Refcursor値が無効です。
    ORA-17443 NULLのユーザーまたはパスワードは、THINドライバでサポートされません。
    ORA-17444 サーバーから受け取ったTTCプロトコル・バージョンはサポートされません。


参考ページ
JDBC Note
Sun JDBC ガイド
Sun JDBC ドキュメント
Oracle8 JDBC Drivers
Oracle 8i jdbc API


まとめ

JDBC の使い方

  1. 必要なドライバをロードします。
  2. 使用するデータベースを指定します。
  3. データベースに接続します。
  4. コネクションを通して SQL 文を送り、結果を受け取ります。