HSPでDBを扱うスクリプト

 

- 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