このページは、以下の英語ページの抄訳です。最新の情報については、
英語ページを参照してください。
このブログ記事のオリジナルは、 Glenn Paulley が Microsoft Excel から SQL Anywhere データベースへのデータのインポートについて 2009 年 11 月に sybase.com に掲載したものです。
Microsoft Excel シートからSQL Anywhere データベースへ、データをインポートする方法の1つに、DBISQL経由での
INPUT 文
があります。 以下にその例を示します。
- INPUT USING 'dsn=myExcelFile;DSN=myExcelFile'
- FROM "myData" INTO "T"
- CREATE TABLE ON
これは、SQL 文というよりは、サーバーが実行できる DBISQL 文であることに注意してください。この文のコンポーネントは、以下のとおりです。
- "myData" は、Excel シートにおける行と列の名づけられたマトリックスを参照し、それを
INPUT
文へのインプットとして使用します。Excel Office 2007 では、以下のステップを実行して、セルの名づけられたマトリックスを作成します。
- マウスで、あるいはShift + 矢印キーを使って、求める行と列のセットをハイライトして選択します。
- ハイライトしたら、選択した行の上で右クリックします。
- スクロールして、 "Name a Range...." でEnter を押すか左クリックします。
- この行のマトリックスに選んだ名前を入力します。ここでは、上の
INPUT
文に対応するよう、"myData" とします。
- 修正したシートを保存します。
- DSN=. DBISQL が Microsoft Excel ODBC ドライバーに接続して"myData" が対応する行と列を読むために ODBC DSN を作成する必要があります。 DSN を作成するには、
- SQL Anywhere プログラムフォルダーから、Microsoft ODBC Administrator をスタートします。"System DSN" にタブをスイッチし、"Add" をクリックします。いくつかのシナリオでは、ユーザーDSN が見つからないことがあるため、システムDSN を使うことが重要です。
- Excel ODBC ドライバーを選択します。私のラップトップでは、まだ32-bit Windows XP が動いているので、以下の2つのExcel ODBC ドライバーが利用可能です。
- ジェネリックな .xls ドライバー ("Microsoft Excel Driver (*.xls)"), version 4.00.6305.00, dated 4/14/2008; と
- Office 2007 ドライバー ("Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)"), version 12.00.6211.1000, dated 8/24/2007.
- 上記のうち1つを選択し、"Finish" をクリックします。
- 様々なドライバーパラメーターのインプットボックスとともにダイアログが表示されます。データソース名を入力して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 のアプリケーションの例を提供してくれました。
- import java.io.*;
- import java.sql.*;
- import java.util.*;
- class T
- {
- public static void main (String args[]) throws IOException
- {
- Connection con = null;
- System.out.println ( "Starting ... " );
- con = connect();
- if( con == null ) {
- return;
- }
- System.out.println ( "Connected ... " );
- try {
- try {
- con.setAutoCommit(false);
- } catch( SQLException dummy ) {
- }
- ResultSet rs = con.getMetaData().getColumns( null, null, "myExcelFile", null );
- int colnum = 1;
- while( rs.next() ) {
- System.out.println( "Column " + colnum + " is named " + rs.getString(4)
- + " with type " + rs.getString(6) + " with size/prec " + rs.getString(7)
- + " with scale " + rs.getString(9) );
- ++colnum;
- }
- rs.close();
- System.out.println( "\n\n" );
- Statement stmt = con.createStatement();
- stmt.setFetchSize(1);
- rs = stmt.executeQuery( "select * from myData" );
- int colcount = rs.getMetaData().getColumnCount();
- int rownum = 1;
- while( rs.next() ) {
- System.out.print( "ROW " + rownum + ": " );
- ++rownum;
- for( int i = 1; i < colcount; ++i ) {
- System.out.print( rs.getObject(i) + " === " );
- }
- System.out.println( rs.getObject(colcount) );
- }
- rs.close();
- con.close();
- System.out.println( "Disconnected" );
- } catch (SQLException sqe) {
- printExceptions(sqe);
- }
- }
- private static Connection connect()
- {
- String driver, url;
- Connection connection;
-
-
-
- System.out.println( "Using Easysoft JDBC-ODBC bridge..." );
- driver="easysoft.sql.jobDriver";
- url="jdbc:easysoft://localhost:8831/myData:trace=on";
- try {
- Class.forName( driver );
- connection = DriverManager.getConnection( url, "dba", "sql" );
- }
- catch( Exception e ) {
- System.err.println( "Error! Could not connect" );
- System.err.println( e.getMessage() );
- printExceptions( (SQLException)e );
- connection = null;
- }
- return connection;
- }
- static private void printExceptions(SQLException sqe)
- {
- while (sqe != null)
- {
- System.out.println("Unexpected exception : " +
- "SqlState: " + sqe.getSQLState() +
- " " + sqe.toString() +
- ", ErrorCode: " + sqe.getErrorCode());
- System.out.println( "======================================" );
- sqe = sqe.getNextException();
- }
- }
- }
結局、残念ながら、安全を考えた場合、Excel から、CSV ファイルなどのような、ロードに際してより修正可能なものへエクスポートした方が良いようです。
そうすることで、データをロードするための様々な
LOAD TABLE
オプション を使用することができ、T の各列に使用されるデータタイプを明示的にコントロールすることができます。
===
SAP SQL Anywhere に関する詳細情報は、<英語> を参照してください。
上記のコミュニティーに掲載されている技術情報は、順次
SQL Anywhere 日本語コミュニティ
に掲載しています。
SQL Anywhere に関してはまずは
こちらをご参照ください。無期限でご利用いただける無償の Developers Edition もこちらからダウンロードが可能です。
SQL Anywhere に関して技術的な質問のある方はコミュニティに登録し、
「Ask a Question」機能をご利用ください。
Language には「Japanese」、
Primary Tag には「SAP SQL Anywhere」を選択
User Tagに「sql anywhere」「sql anywhere Japanese question」
を入力してください。
不具合につきましては、サポート契約者様専用の問い合わせ方法にてお問い合わせください。
======================
ご購入に関するお問い合わせ
こちらよりお問い合わせください。