アカウント


 



Firebird日本ユーザー会はFirebird Foundation の公式スポンサーです
Firebird日本ユーザー会は
Firebird Foundation の
公式スポンサーです

JayBird と ShiftJIS データベース

[Firebird-jp-general][00960] ~が文字化ける

■環境
FrieBird1.5
JayBird1.0
Java1.4.2
上記の環境でDBから「~」の入った文字を取得すると
「?」と文字化けしています。
解決策はないのでしょうか
ちなみに、今までMYSQLを使用していたのですが文字化け
したことなかったので。。。
なお、DBもSJISでJDBCドライバロード時にSJIS指定しています。

[Firebird-jp-general][00967] Re: [00960] ~が文字化ける

環境は「クライアントがWindowsかどうか」も影響します。
Windows上でJavaアプリを作っているものと想定します。
JDBCドライバ中に isc_encodings.properties と言うファイルが
あります。(バージョンによって内容は違うかもしれませんが)該当
ファイル中に
| #Windows Japanese
| SJIS_0208       MS932
| 
| #Shift-JIS, Japanese
| SJIS_0208       SJIS
と言う記述があるので、下をコメントにしてもう一度jarファイルを
生成しなおしてください。
「FireBirdの SJIS_0208 は、Java の MS932」と言う関連付けを
しなければ、Windowsでは文字化けします。
(逆に、Windows以外では SJIS_0208 <-> SJISでないと駄目)
他のD/BのJDBCドライバでは普通クライアントコード側で指定できる
ものですが、JayBird(FirebirdSQL)はそうなっていないようです。
# ソースを見てないのでできるのかもしれませんが。
これによる弊害として、クライアントOSが不定となるAppletや
JavaWebStartで SJIS_0208が使用できない、と言うことがあげられます。

firebirdsql-full.jarの修正とテスト

早速、firebirdsql-full.jarを修正してみました。
>jar xf firebirdsql-full.jar
として、jarファイルを解凍します。isc_encodings.properties の該当箇所を編集後、
>jar cf firebirdsql-full-win.jar *
として、jarファイルを作成します。
次に、JayBirdのサンプルコードをばっさりと切り捨てながらシンプルなテストコードを作成。
(Example.java)
public class Example
{
  public static void main (String args[]) throws Exception
  {
    String databaseURL = "jdbc:firebirdsql:localhost/3050:d:/db/test.gdb?lc_ctype=SJIS_0208";
    String user = "sysdba";
    String password = "masterkey";
    try { 
      password = args[0];
    } catch (ArrayIndexOutOfBoundsException e) { 
      // At least an argument is needed
      System.out.println("Password is needed"); 
      System.out.println(e.getMessage()); 
      return; 
    }
    String driverName = "org.firebirdsql.jdbc.FBDriver";
    java.sql.Driver d = null;
    java.sql.Connection c = null;
    java.sql.Statement s = null;
    java.sql.ResultSet rs = null;
    try {
      try {
        Class.forName ("org.firebirdsql.jdbc.FBDriver");
      }
      catch (java.lang.ClassNotFoundException e) {
        // A call to Class.forName() forces us to consider this exception :-)...
        System.out.println ("Firebird JCA-JDBC driver not found in class path");
        System.out.println (e.getMessage ());
        return;
      }
      try {
        // We pass the entire database URL, but we could just pass "jdbc:interbase:"
        d = java.sql.DriverManager.getDriver (databaseURL);
        System.out.println ("Firebird JCA-JDBC driver version " +
                            d.getMajorVersion () +
                            "." +
                            d.getMinorVersion () +
                            " registered with driver manager.");
      }
      catch (java.sql.SQLException e) {
        System.out.println ("Unable to find Firebird JCA-JDBC driver among the registered drivers.");
        showSQLException (e);
        return;
      }
      try {
        c = java.sql.DriverManager.getConnection (databaseURL, user, password);
        System.out.println ("Connection established.");
      }
      catch (java.sql.SQLException e) {
        System.out.println ("Unable to establish a connection through the driver manager.");
        showSQLException (e);
        return;
      }
      // Let's disable the default autocommit so we can undo our changes later...
      try {
        c.setAutoCommit (false);
        System.out.println ("Auto-commit is disabled.");
      }
      catch (java.sql.SQLException e) {
        System.out.println ("Unable to disable autocommit.");
        showSQLException (e);
        return;
      }
      try {
        s = c.createStatement ();
        rs = s.executeQuery ("select name1 from t_japanese");
      }
      catch (java.sql.SQLException e) {
        System.out.println ("Unable to submit a static SQL query.");
        showSQLException (e);
        // We can't go much further without a result set, return...
        return;
      }
      try {
        java.sql.ResultSetMetaData rsMetaData = rs.getMetaData ();
        System.out.println ("The query executed has " +
                            rsMetaData.getColumnCount () +
                            " result columns.");
        System.out.println ("Here are the columns: ");
        for (int i = 1; i >= rsMetaData.getColumnCount (); i++) {
          System.out.println (rsMetaData.getColumnName (i) +
                              " of type " +
                              rsMetaData.getColumnTypeName (i));
        }
      }
      catch (java.sql.SQLException e) {
        System.out.println ("Unable to extract result set meta data.");
        showSQLException (e);
        // What the heck, who needs meta data anyway ;-(, let's continue on...
      }
      // Ok, lets step thru the results of the query...
      try {
        System.out.println ("t_japanese name1 is printed bellow...");
        while (rs.next ()) {
          System.out.println (rs.getString ("name1"));
        }
      }
      catch (java.sql.SQLException e) {
        System.out.println ("Unable to step thru results of query");
        showSQLException (e);
        return;
      }
    }
    // This finally clause will be executed even if "return" was called in case of any exceptions above.
    finally {
      System.out.println ("Closing database resources and rolling back any changes we made to the database.");
      // Now that we're all finished, let's release database resources.
      try { if (rs!=null) rs.close (); } catch (java.sql.SQLException e) { showSQLException (e); }
      try { if (s!=null) s.close (); } catch (java.sql.SQLException e) { showSQLException (e); }
      // Before we close the connection, let's rollback any changes we may have made.
      try { if (c!=null) c.rollback (); } catch (java.sql.SQLException e) { showSQLException (e); }
      try { if (c!=null) c.close (); } catch (java.sql.SQLException e) { showSQLException (e); }
    }
  }
  // Display an SQLException which has occured in this application.
  private static void showSQLException (java.sql.SQLException e)
  {
    // Notice that a SQLException is actually a chain of SQLExceptions,
    // let's not forget to print all of them...
    java.sql.SQLException next = e;
    while (next != null) {
      System.out.println (next.getMessage ());
      System.out.println ("Error Code: " + next.getErrorCode ());
      System.out.println ("SQL State: " + next.getSQLState ());
      next = next.getNextException ();
    }
  }
}
sdkのコンパイラでコンパイルして、実行。
>javac -classpath firebirdsql-full-win.jar Example.java
>java -classpath .;firebirdsql-full-win.jar Example hogehoge
Firebird JCA-JDBC driver version 0.1 registered with driver manager.
Connection established.
Auto-commit is disabled.
The query executed has 1 result columns.
Here are the columns:
NAME1 of type CHAR
t_japanese name1 is printed bellow...
ほげほげ
ぷー
それ~どうした
次に、オリジナルのjarファイルを指定して、実行してみます。

>java -classpath .;firebirdsql-full.jar Example hogehoge
Firebird JCA-JDBC driver version 0.1 registered with driver manager.
Connection established.
Auto-commit is disabled.
The query executed has 1 result columns.
Here are the columns:
NAME1 of type CHAR
t_japanese name1 is printed bellow...
ほげほげ
ぷー
それ?どうした

文字化けしていることが確認出来ました。

テストテーブルは、以下の通りです。

CREATE TABLE "T_JAPANESE" 
(
  "NAME1"  CHAR(10) CHARACTER SET SJIS_0208
)

2010年10月にFirebird2.5がリリースされました。SuperClassicエンジンの実装により、よりパワフルに、よりスケーラブルになりました。(2012/11/6)
powered by Sylph  version.1.0 rc4 / ©1998-2004.DipMeshSystems .