- I N D E X -
ODBCを使ってDBを操作するサンプルとして試しに作成したスクリプトです。
SQLを使ってAccessのmdbファイルを操作できます。
ODBCがインストールされている必要があります。
HSP拡張プラグインとしてForceさんのApex.dll(ver0.4)を使っています。
途中の s_ConStrIn = "DRIVER=〜 を変更することによってODBCで設定されたSQLサーバにもアクセスができます。
このスクリプトは無保証です。使用の際は個人の責任において使用してください。
▲ データはインターネットに落ちていたサンプルのmdbファイルから拝借しました。(^^;)
使用OS :Windows NT Workstation 4.00 SP5 + IE 5.01 使用OCBD マネージャ:Microsoft ODBC Driver Manager (3.510.3711.0) ドライバ :Microsoft ODBC Desktop Driver Pack 3.5 (3.51.1713.00) HSP : ver v2.5 HSP plugin: Apex v0.04 (By FORCEさん)
;////////////////////////////////////////////////////////////////////////////// ; Access 用ファイルを ODBC経由でSQLを使って扱うスクリプト for HSP 2.5 ; By Dateshim. 2000/01/25 ver ;////////////////////////////////////////////////////////////////////////////// ; ;[作成環境] ;使用OS :Windows NT Workstation 4.00 SP5 + IE 5.01 ;使用OCBDドライバ ; マネージャ:Microsoft ODBC Driver Manager (3.510.3711.0) ; ドライバ :Microsoft ODBC Desktop Driver Pack 3.5 (3.51.1713.00) ;============================================================================== ; HSP拡張DLLの設定 ;============================================================================== #include "Apex.as" ;Apex v0.4 by FORCE ;============================================================================== ; ODBC用文字定数の定義 (Microsoft Visual C++ 5 の sql.h ,sqlex.h より抜粋) ;============================================================================== #define NULL 0 ;/* return values from functions */ #define SQL_SUCCESS 0 #define SQL_SUCCESS_WITH_INFO 1 #define SQL_STILL_EXECUTING 2 #define SQL_NEED_DATA 99 #define SQL_NO_DATA 100 #define SQL_ERROR $0000ffff ;(-2) #define SQL_INVALID_HANDLE $0000fffe ;(-1) ;/* flags for null-terminated string */ #define SQL_NTS -3 ;/* Options for SQLDriverConnect */ #define SQL_DRIVER_NOPROMPT 0 #define SQL_DRIVER_COMPLETE 1 #define SQL_DRIVER_PROMPT 2 #define SQL_DRIVER_COMPLETE_REQUIRED 3 ;/* FreeStmt() options */ #define SQL_CLOSE 0 #define SQL_DROP 1 #define SQL_UNBIND 2 #define SQL_RESET_PARAMS 3 ;/* SQL data type codes */ #define SQL_UNKNOWN_TYPE 0 #define SQL_CHAR 1 #define SQL_NUMERIC 2 #define SQL_DECIMAL 3 #define SQL_INTEGER 4 #define SQL_SMALLINT 5 #define SQL_FLOAT 6 #define SQL_REAL 7 #define SQL_DOUBLE 8 #define SQL_DATETIME 9 #define SQL_VARCHAR 12 ;/* One-parameter shortcuts for date/time data types */ #define SQL_TYPE_DATE 91 #define SQL_TYPE_TIME 92 #define SQL_TYPE_TIMESTAMP 93 ;============================================================================== ; 初期設定 ;============================================================================== #define BRWS_LEN 1000 ;ブラウズ用の最大バッファサイズ #define SQL_LEN 1000 ;SQL文の最大サイズ #define RES_LEN 32000 ;結果の保存用バッファサイズ ;//Apex.dllの初期設定 apx_ver ;Apex.dllのヴァージョンのチェック if stat<40 { dialog "Apex.dllのバージョンが古いため、動作が保証できません." ,1,"Apex v0.4 以上を使用してください" end } apx_set ret,2 ;リターンバッファを指定 ;(ODBC関連の関数の戻り値はsigned short型だからWORD長を指定) ;//odbcjt32.dllをロード apx_load "odbc32.dll" ;DLLをロード hUsr=ret ;ハンドルを取得 if hUsr==0 { dialog "odbc32.dllのロードに失敗しました.",1,"ODBCをインストールしてください" end } ;//使用変数の定義 p_henv=0 ;HREV p_hrev (typedef void* HREV) p_hdbc=0 ;HDBC p_hdbc (typedef void* HDBC) p_hstmt=0 ;HSTMT p_hstmt (typedef void* HSTMT) i_ConStrOut=0 ;取得データの文字列長 sdim s_ConStrIn ,BRWS_LEN ;ODBCドライバ接続要求の送信データ sdim s_ConStrOut,BRWS_LEN ;ODBCドライバ接続結果の取得バッファ sdim s_SQLSTR,SQL_LEN ;SQLリクエスト用 sdim s_SQLRCV,SQL_LEN ;SQL結果受信用 sdim s_RETSTR,RES_LEN ;結果表示用 s_ConStrIn = "DRIVER={Microsoft Access Driver (*.mdb)}" ; s_ConStrIn = "DRIVER={SQL Server};SERVER=hoge;UID=user;PWD=pass" ; s_ConStrIn = "DRIVER={Microsoft Excel Driver (*.xls)}" ;ここではAccess(*.mdb)ファイル用のODBCドライバを選択 ;ドライバーを変更すればSQLサーバや他のDBソフトの情報にもアクセスできる。 ;ここでファイル等も直接設定できる。 ;============================================================================== ; 環境領域・接続用ワークエリアの確保 ;============================================================================== ;//RETCODE SQLAllocEnv(&henv); dim prm,1 ;引数の数 = 1 apx_ptr p_henv ;変数p_henvへのポインタを取得 prm.0=ret ;引数に代入 apx_call prm,"SQLAllocEnv",1,hUsr ;SQLAllocEnv関数の呼出し if ret!=SQL_SUCCESS : dialog "Error! (SQLAllocEnv)",1,"(>_<)" :goto *quit_proc_5 mes "関数(SQLAllocEnv)が成功しました." ;//SQLAllocConnect(henv, &hdbc); dim prm,2 ;引数の数 = 2 prm.0=p_henv ;第1引数にp_henvを代入 apx_ptr p_hdbc ;変数p_hdbcへのポインタを取得 prm.1=ret ; 〃 を第2引数に代入 apx_call prm,"SQLAllocConnect",2,hUsr ;SQLAllocConnect関数の呼出し if ret!=SQL_SUCCESS : dialog "Error! (SQLAllocConnect)",1,"(>_<)" :goto *quit_proc_4 mes "関数(SQLAllocConnect)が成功しました." onexit *quit_proc_3 ;============================================================================== ; ODBCドライバへの接続 ;============================================================================== ;//SQLDriverConnect(hdbc, NULL, s_ConnStrIn, i_ConnStrInLen, s_ConnStrOut, i_ConnStrOutMax, i_ConnStrOut, fDriverCompletion) dim prm,8 ;引数の数 = 8 prm.0=p_hdbc,NULL,0,BRWS_LEN,0,BRWS_LEN,0,SQL_DRIVER_COMPLETE_REQUIRED apx_ptr s_ConStrIn ;変数s_ConStrInへのポインタを取得 prm.2=ret ; 〃 を第3引数に代入 apx_ptr s_ConStrOut ;変数s_ConStrOutへのポインタを取得 prm.4=ret ; 〃 を第5引数に代入 apx_ptr i_ConStrOut ;変数i_ConStrOutへのポインタを取得 prm.6=ret ; 〃 を第7引数に代入 s_funcname="SQLDriverConnect":i_agmc=8 gosub call_api ;SQLBrouseConnect関数の呼出し if stat=1 : goto *quit_proc_3 dialog "DB設定条件\t : "+s_ConStrOut,0,"データベースに接続しました" onexit *quit_proc_2 ;============================================================================== ; 画面の作成 ;============================================================================== cls objmode 1 s_SQLSTR="" input s_SQLSTR,640 button "SQL実行",*sql_access mesbox s_RETSTR,640,430 stop ;============================================================================== ; ステートメントハンドルの取得 ;============================================================================== *sql_access ;//SQLAllocStmt(p_hdbc, &p_hstmt); dim prm,2 ;引数の数 = 2 prm.0=p_hdbc ;第1引数にp_hdbcを代入 apx_ptr p_hstmt ;変数p_hstmtへのポインタを取得 prm.1=ret ; 〃 を第2引数に代入 apx_call prm,"SQLAllocStmt",2,hUsr ;SQLAllocStmt関数の呼出し if (ret!=SQL_SUCCESS) : dialog "Error! (SQLAllocStmt)",1,"(>_<)":goto *quit_proc_2 ;============================================================================== ; データーベースへのアクセス ;============================================================================== s_RETSTR ="" ;//リクエスト送信 ;//SQLExecDirect(p_hstmt, s_SQLSTR, SQL_LEN); strlen i_sql_len,s_SQLSTR ;SQL文の文字列長をi_sql_lenに取得 dim prm,3 ;引数の数 = 3 prm.0=p_hstmt,0,i_sql_len ;第1引数にp_hstmtを代入 ;第3引数にi_sql_lenを代入 apx_ptr s_SQLSTR ;変数s_SQLSTRへのポインタを取得 prm.1=ret ; 〃 を第2引数に代入 s_funcname="SQLExecDirect":i_agmc=3 gosub call_api ;SQLExecDirect関数の呼出し if stat=1 : goto *quit_proc_1 ;//結果受信 repeat ;//SQLFetch(hstmt); //fetches a row of data from a result set. dim prm,1 ;引数の数 = 1 prm.0=p_hstmt ;引数にp_hstmtを代入 apx_call prm,"SQLFetch",1,hUsr.0 ;SQLFetch関数の呼出し if (ret!=SQL_SUCCESS) : break ;データが無ければbreak repeat ;//SQLGetData(hstmt, 1, SQL_CHAR, szName, NAME_LEN, &cbName); dim prm,6 ;引数の数 = 6 prm.0=p_hstmt,cnt+1,SQL_CHAR,0,SQL_LEN,0 ;第1引数にp_hstmtを代入 ;第2引数に取得カラムを代入 ;第3引数にSQL_CHAR (文字列型で取得)を代入 ;第5引数にSQL_LENを代入 apx_ptr s_SQLRCV ;変数s_SQLRCVへのポインタを取得 prm.3=ret ; 〃 を第4引数に代入 apx_ptr i_ConStrOut ;変数i_ConStrOutへのポインタを取得 prm.5=ret ; 〃 を第6引数に代入 apx_call prm,"SQLGetData",6,hUsr ;SQLGetData関数の呼出し if (ret!=SQL_SUCCESS) : break ;データが無ければbreak s_RETSTR += s_SQLRCV+"\t" ;結果の追加+タブ文字の挿入 loop s_RETSTR += "\n" ;改行 loop objprm 2,s_RETSTR ;============================================================================== ; ステートメントハンドルの解放 ;============================================================================== *quit_proc_1 ;//SQLFreeStmt(hstmt, fOption) dim prm,2 ;引数の数 = 2 prm.0=p_hstmt,SQL_DROP ;第1引数にp_hdbcを代入 ;第2引数にSQL_DROPを代入 apx_call prm,"SQLFreeStmt",2,hUsr ;SQLFreeStmt関数の呼出し if (ret!=SQL_SUCCESS) : dialog "Error! (SQLFreeStmt)",1,"(>_<)" stop ;============================================================================== ; ODBCからの切断 ;============================================================================== *quit_proc_2 ;//SQLDisconnect(hdbc); dim prm,1 ;引数の数 = 1 prm.0=p_hdbc ;引数にp_hdbcを代入 apx_call prm,"SQLDisconnect",1,hUsr ;SQLFreeConnect関数の呼出し if ret!=SQL_SUCCESS : dialog "Error! (SQLDisconnect)",1,"(>_<)" ;============================================================================== ; 環境領域・接続用ワークエリアの解放 ;============================================================================== *quit_proc_3 ;//SQLFreeConnect(hdbc); dim prm,1 ;引数の数 = 1 prm.0=p_hdbc ;引数にp_hdbcを代入 apx_call prm,"SQLFreeConnect",1,hUsr ;SQLFreeConnect関数の呼出し if ret!=SQL_SUCCESS : dialog "Error! (SQLFreeConnect)",1,"(>_<)" *quit_proc_4 ;//SQLFreeEnv(henv); dim prm,1 ;引数の数 = 1 prm.0=p_henv ;引数にp_henvを代入 apx_call prm,"SQLFreeEnv",1,hUsr ;SQLFreeEnv関数の呼出し if ret!=SQL_SUCCESS : dialog "Error! (SQLFreeEnv):"+stat,1,"(>_<)"+ret ;============================================================================== ; 後処理 ;============================================================================== *quit_proc_5 ;//odbcjt32.dllの解放 apx_free hUsr end ;============================================================================== ; API関数呼出しサブルーチン ;============================================================================== *call_api mref i_stat,64 apx_call prm,s_funcname,i_agmc,hUsr ;API関数の呼出し if (ret != SQL_SUCCESS)&&(ret !=SQL_SUCCESS_WITH_INFO) { x_code=ret str x_code,20 ;4桁の16進に変換 if ret=SQL_NO_DATA : x_code+="(情報がありません)" if ret=SQL_NEED_DATA : x_code+="(情報が必要です)" if ret=SQL_INVALID_HANDLE : x_code+="(ハンドルが不正です)" if ret=SQL_STILL_EXECUTING : x_code+="(既に実行中です)" dialog "Apex return code:"+stat+"\nAPI return code:"+x_code,1,"(>_<) Error! ("+s_funcname+"関数)" ;//エラー関数の呼出し ;//SQLError(henv, hdbc, hstmt, s_SqlState, p_NativeError, s_ErrorMsg, BRWS_LEN, s_ErrorMsgCode) if ret=SQL_ERROR { sdim s_SqlState,BRWS_LEN ;エラー詳細取得用変数の初期化 sdim s_ErrorMsg,BRWS_LEN ; p_NativeError=0 ; i_ErrorMsgCode=0 ; dim prm,8 ;引数の数 = 8 prm.0=p_henv, p_hdbc, p_hstmt,0,0,0,BRWS_LEN,0 apx_ptr s_SqlState ;変数s_SqlStateへのポインタを取得 prm.3=ret ;第4引数に代入 apx_ptr p_NativeError ;変数p_NativeErrorへのポインタを取得 prm.4=ret ;第5引数に代入 apx_ptr s_ErrorMsg ;変数s_ErrorMsgへのポインタを取得 prm.5=ret ;第6引数に代入 apx_ptr i_ErrorCnt ;変数s_ErrorMsgCodeへのポインタを取得 prm.7=ret ;第8引数に代入 apx_call prm,"SQLError",8,hUsr.0 ;SQLError関数の呼出し x_code=p_NativeError str x_code,24 ;4桁の16進に変換 dialog "SqlState : "+s_SqlState+"\nNativeError : "+x_code+"\nErrorMsg : "+s_ErrorMsg,0,"エラー詳細" } i_stat=1 } else { i_stat=0 } return ;______________________________________________________________________________
SQLDriverConnect 関数の接続先を指定する引数
s_ConStrInには次のキーワードが使えます. (主にSQL Serverに接続する場合)
キーワード 意味の説明 DSN アクセスの対象にするデータソースの名前。キーワードDRIVERが指定されている場合、キーワードDSNは使用しません。 DRIVER 使用するODBCドライバーの名前。キーワードDSNが指定されている場合、キーワードDRIVERは使用しません。ドライバーの名前は中括弧でくくります。 SERVER アクセスの対象にするデータソースのあるネットワーク上のサーバ名を指定します。 UID サーバーやDBへのアクセスに使用するログインユーザ名。 PWD パスワード。 APP SQLDriverConnect を呼び出すアプリケーション名(省略可) DATABASE SQL Server のデータベース名 (省略可) LANGUAGE SQL Server を使用する際の言語の選択(省略可) 使用例
データソース名(DSN)がHuman Resourcesでデータベース名がPayrollのデータベースに、ユーザ名 Smith パスワード Sesame で接続する場合:
DSN=Human Resources;UID=Smith;PWD=Sesame;DATABASE=Payroll
SQL Server が走っているサーバー名を直接指定して接続する(ODBCのデータソース名DNSを使わない)場合:
DRIVER={SQL Server};SERVER=hrserver;UID=Smith;PWD=Sesame;DATABASE=Payroll
Access のファイルを参照する場合:
DRIVER={Microsoft Access Driver (*.mdb)}
Access のファイル(D:\home\dateshim\データ.MDB)を直接参照する場合:
DRIVER={Microsoft Access Driver (*.mdb)};DBQ=D:\\home\\dateshim\\データ.MDB