Skip to Content

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

 

 

 

このブログ記事のオリジナルは、 Glenn Paulley が Microsoft Excel から SQL Anywhere データベースへのデータのインポートについて 2009 年 11 月に sybase.com に掲載したものです。

 

 

Microsoft Excel シートからSQL Anywhere データベースへ、データをインポートする方法の1つに、DBISQL経由での INPUT 文があります。 以下にその例を示します。

 

  1. INPUT USING ‘dsn=myExcelFile;DSN=myExcelFile’
  2. FROM “myData” INTO “T”
  3. CREATE TABLE ON

 

これは、SQL 文というよりは、サーバーが実行できる DBISQL 文であることに注意してください。この文のコンポーネントは、以下のとおりです。

  • “myData” は、Excel シートにおける行と列の名づけられたマトリックスを参照し、それをINPUT 文へのインプットとして使用します。Excel Office 2007 では、以下のステップを実行して、セルの名づけられたマトリックスを作成します。
    1. マウスで、あるいはShift + 矢印キーを使って、求める行と列のセットをハイライトして選択します。
    2. ハイライトしたら、選択した行の上で右クリックします。
    3. スクロールして、 “Name a Range….” でEnter を押すか左クリックします。
    4. この行のマトリックスに選んだ名前を入力します。ここでは、上のINPUT 文に対応するよう、”myData” とします。
    5. 修正したシートを保存します。
  • DSN=. DBISQL が Microsoft Excel ODBC ドライバーに接続して”myData” が対応する行と列を読むために ODBC DSN を作成する必要があります。 DSN を作成するには、
    1. SQL Anywhere プログラムフォルダーから、Microsoft ODBC Administrator をスタートします。”System DSN” にタブをスイッチし、”Add” をクリックします。いくつかのシナリオでは、ユーザーDSN が見つからないことがあるため、システムDSN を使うことが重要です。
    2. Excel ODBC ドライバーを選択します。私のラップトップでは、まだ32-bit  Windows XP が動いているので、以下の2つのExcel ODBC ドライバーが利用可能です。
      1. ジェネリックな .xls ドライバー (“Microsoft Excel Driver (*.xls)”), version 4.00.6305.00, dated 4/14/2008; と
      2. Office 2007 ドライバー (“Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)”), version 12.00.6211.1000, dated 8/24/2007.
    3. 上記のうち1つを選択し、”Finish” をクリックします。
    4. 様々なドライバーパラメーターのインプットボックスとともにダイアログが表示されます。データソース名を入力してDSN に名前をつけ ( 我々は”myExcelFile” を選択しました)、”Browse” ボタンを使用して、ODBC Administrator に対して、ファイルシステムのどこにそのシートがあるかを教えます。そして、”OK”をクリックします。
  • そのFROM "myData" INTO "T" シンタックスは、DBISQL に”myData”と名づけられたデータレンジから”T” というテーブルを作成するように指示します。

 

Et voila ( はい) !  選択した行と列をSQL Anywhere の 「T」 という名のテーブルにインポートできました。

 

If Only It Were That Simple (そんなに簡単なら良いのだけれど)

 

上記のステップのセットで、たしかにインポートできます 。本当に。 この方法は、私が SQL Anywhere 11.0.1 のマニュアルに記載したExcel 2007 の行と列のマトリックスの名前付けをするステップとは異なりますが…。また、11.0.1 のマニュアルでは、Office 2003 バージョンのExcel を使用する場合のステップについて詳細に説明しています。

 

余談ですが: SQL Anywhere 11.0.1 のマニュアルには、以下のことが抜けています。Microsoft ODBC ドライバーは、名前がつけられた行と列のセットの最初の行にデータの “column names” が含まれていると仮定し、この結果セットに対するメタデータの呼び出しに対応してこれらのセル値を返します。そのため、ロードする行と列のセットに名前をつける場合には、最初の列に必ずテーブル”T” に希望する列の名前を含むようにする必要があります- DBISQL INPUT 文で、DBISQL は、根本にあるODBC ドライバーへのメタデータの呼び出しで返される列の名前を使用します。

 

しかしながら、この方法で Excel のデータをインポートするには、2つの重要な(そして関連する)問題があります。そしてこれら2つは、Microsoft Excel ODBC ドライバーによる問題です(私が上に記載したドライバー2つのどちらでも同じ動きをしました)。2つの問題とは:

  • Excel 用 Microsoft ODBC ドライバーは、明らかに名前をつけられたエリアの様々な列のデータタイプを任意に選択します。そして
  • データ例外が発生することがあります。なぜならば、データタイプの選択が、全セルのコンテンツにマッチしないことがあるからです。 Excel ODBC ドライバー経由で、いかにデータセットが正確にFETCH されるかによって、アプリケーションは、 (1) エラーを受け取る、または (2) データ例外の結果になる値が NULL として返される、または (3) 結果セットが、何の通知もなくtruncate される、になります。

 

Excel のドライバーが、セルの各列にどのデータタイプを選択するかについては、この2003 Microsoft Knowledge Base 記事に説明されています。Excel シートのデータが醜い場合、ドライバーに(string のような)よりジェネリックなタイプを選択するよう強制すること、ほとんどできないようです。そして、このデータタイプの選択が、2つ目の問題を引き起こします。

 

この DBISQL INPUT 文は、ワイドフェッチを使用して DBISQL に Excel のデータソース上にカーソルをオープンさせます。 – そして、最初のデータ例外時に、Microsoft ドライバーは、end-of-file を返し、結果セットは効果的にエラーなしに trancate されます。私は、その他 2つのJDBC-ODBC ブリッジ – 無償で手に入るSun Microsystems のブリッジと商用のEasysoft JDBC-ODBC bridge(無償試使用) で実験してみました – そして、そしてどちらのドライバーでも、少し異なる動きを示しました。完全な結果セットを返しましたが、エラーを示すことなく、NULL に置き換わる無効なデータ値でした。私の同僚の Karim Khamis がこの動きをお見せする Java のアプリケーションの例を提供してくれました。

 

  1. import java.io.*;
  2. import java.sql.*;
  3. import java.util.*;
  4. class T
  5. {
  6.     public static void main (String args[]) throws IOException
  7.     {
  8.   Connection    con = null;
  9.   System.out.println ( “Starting … “ );
  10.   con = connect();
  11.   if( con == null ) {
  12.     return; // exception should already have been reported
  13.   }
  14.   System.out.println ( “Connected … “ );
  15.   try {
  16.     try {
  17.   con.setAutoCommit(false);
  18.     } catch( SQLException dummy ) {
  19.     }
  20.     ResultSet rs = con.getMetaData().getColumns( null, null, “myExcelFile”, null );
  21.     int colnum = 1;
  22.     while( rs.next() ) {
  23.         System.out.println( “Column “ + colnum + ” is named “ + rs.getString(4)
  24.                     + ” with type “ + rs.getString(6) + ” with size/prec “ + rs.getString(7)
  25.                     + ” with scale “ + rs.getString(9) );
  26.   ++colnum;
  27.     }
  28.     rs.close();
  29.     System.out.println( “\n\n” );
  30.     Statement stmt = con.createStatement();
  31.     stmt.setFetchSize(1); // set to > 1 to enable wide fetches if supported
  32.     rs = stmt.executeQuery( “select * from myData” );
  33.     int colcount = rs.getMetaData().getColumnCount();
  34.     int rownum = 1;
  35.     while( rs.next() ) {
  36.         System.out.print( “ROW “ + rownum + “: “ );
  37.   ++rownum;
  38.   for( int i = 1; i < colcount; ++i ) {
  39.     System.out.print( rs.getObject(i) + ” === “ );
  40.   }
  41.   System.out.println( rs.getObject(colcount) );
  42.     }
  43.     rs.close();
  44.     con.close();
  45.     System.out.println( “Disconnected” );
  46.   } catch (SQLException sqe) {
  47.     printExceptions(sqe);
  48.   }
  49.     }
  50.     private static Connection connect()
  51.     {
  52.   String    driver, url;
  53.   Connection  connection;
  54.   // System.out.println( “Using Sun JDBC-ODBC bridge…” );
  55.   // driver=”sun.jdbc.odbc.JdbcOdbcDriver”;
  56.   // url=”jdbc:odbc:myData”;
  57.   System.out.println( “Using Easysoft JDBC-ODBC bridge…” );
  58.   driver=“easysoft.sql.jobDriver”;
  59.   url=“jdbc:easysoft://localhost:8831/myData:trace=on”;
  60.   try {
  61.     Class.forName( driver );
  62.     connection = DriverManager.getConnection( url, “dba”, “sql” );
  63.   }
  64.   catch( Exception e ) {
  65.     System.err.println( “Error! Could not connect” );
  66.     System.err.println( e.getMessage() );
  67.     printExceptions( (SQLException)e );
  68.     connection = null;
  69.   }
  70.   return connection;
  71.     }
  72.     static private void printExceptions(SQLException sqe)
  73.     {
  74.         while (sqe != null)
  75.         {
  76.     System.out.println(“Unexpected exception : “ +
  77.   “SqlState: “ + sqe.getSQLState()  +
  78.   ” “ + sqe.toString() +
  79.   “, ErrorCode: “ + sqe.getErrorCode());
  80.     System.out.println( “======================================” );
  81.             sqe = sqe.getNextException();
  82.         }
  83.     }
  84. }

結局、残念ながら、安全を考えた場合、Excel から、CSV ファイルなどのような、ロードに際してより修正可能なものへエクスポートした方が良いようです。

そうすることで、データをロードするための様々な LOAD TABLE オプション を使用することができ、T の各列に使用されるデータタイプを明示的にコントロールすることができます。

 

 

 
===

 

SAP SQL Anywhere に関する詳細情報は、SAP SQL Anywhere Communityページ

<英語> を参照してください。

 

上記のコミュニティーに掲載されている技術情報は、順次SQL Anywhere 日本語コミュニティに掲載しています。

SQL Anywhere の日本語記事をリスト形式で表示するには、「sql anywhere japan」のタグをクリックしてください。

 

SQL Anywhere に関してはまずはこちらをご参照ください。無期限でご利用いただける無償の Developers Edition もこちらからダウンロードが可能です。

 

SQL Anywhere に関して技術的な質問のある方はコミュニティに登録し、
「+ Actions」から「Ask a Question」機能をご利用ください。

Language には「Japanese」、
Primary Tag には「SQL Anywhere」、
Additional tag には「SAP SQL Anywhere」、
User Tagに「sql anywhere japanese question」

を選択してください。

不具合につきましては、サポート契約者様専用の問い合わせ方法にてお問い合わせください。

 

======================

ご購入に関するお問い合わせ

 

こちらよりお問い合わせください。

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply