独学プログラミング言語のページ > Windows サンプル ソース > ORACLEに接続する

ORACLEに接続する

OCIを使ってORACLEにアクセスする。Visual C++のメニューバーからツール -オプション-ディレクトリでoci.libのあるフォルダを追加して下さい。

意味
dvoid void
sb4 signed int
ub2 unsigned short
ub4 unsigned int
sword signed int

接続までのOCiの関数です。

sword OCIEnvCreate  ( OCIEnv        **envhpp, 
                      ub4           mode, 
                      CONST dvoid   *ctxp, 
                      CONST dvoid   *(*malocfp) 
                                    (dvoid *ctxp, 
                                        size_t size), 
                      CONST dvoid   *(*ralocfp) 
                                    (dvoid *ctxp, 
                                       dvoid *memptr, 
                                       size_t newsize), 
                      CONST void    (*mfreefp) 
                                    ( dvoid *ctxp, 
                                       dvoid *memptr))
                      size_t    xtramemsz,
                      dvoid     **usrmempp );
sword OCIHandleAlloc ( CONST dvoid   *parenth,
                     dvoid         **hndlpp, 
                     ub4           type, 
                     size_t        xtramem_sz,
                     dvoid         **usrmempp);
sword OCILogon (OCIEnv        *envhp,
                OCIError      *errhp,
                OCISvcCtx     *svchp,
                CONST OraText *username,
                ub4           uname_len,
                CONST OraText *password,
                ub4           passwd_len,
                CONST OraText *dbname,
                ub4           dbname_len
                );

サンプルです。

/*///////////////////////////////////////
//      オラクルに接続
//      oci.lib をリンク
//      
///////////////////////////////////////*/
#include <windows.h>
#include <stdio.h>
#define  IDC_SDK_TEST1      201                 /* ボタンのID */
#define  IDC_SDK_TEST2      202                 /* ボタンのID */

#pragma comment(lib,"oci")
#include <oci.h>
/* #include <ocidfn.h> */

char szClassName[]    = "template";     /* ウィンドウクラス */
char szWindowsTitle[] = "ORACLE";       /* ウィンドウ名 */

HINSTANCE hInst;
static BOOL connection_state;

/* OCIハンドル */
static OCIEnv     *phOciEnv;
static OCIError   *phOciError;
static OCISvcCtx  *phOciSvcCtx;

text *tDbname;
text *tUsername;
text *tPassword;
 
/* 関数プロトタイプ */
static BOOL  errprocessing(HWND, OCIError *, sword);
BOOL connect_oracle(HWND ,text *, text *, text *);
BOOL rearrangement_oracle(HWND);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL InitInstance(HINSTANCE, int);

int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
                                   LPSTR lpsCmdLine, int nCmdShow)
{
        MSG msg;
        BOOL bResult;
        WNDCLASSEX wc;

        hInst = hCurInst;
        /* ウィンドウ・クラスの登録 */
        wc.cbSize = sizeof(WNDCLASSEX);
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc = WndProc;       /* プロシージャ名 */
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hCurInst;        /* インスタンス */
        wc.hIcon = (HICON)LoadImage(NULL,
                MAKEINTRESOURCE(IDI_APPLICATION),
                IMAGE_ICON,
                0,
                0,
                LR_DEFAULTSIZE | LR_SHARED);
        wc.hCursor = (HCURSOR)LoadImage(NULL,
        MAKEINTRESOURCE(IDC_ARROW),
        IMAGE_CURSOR,
                0,
                0,
                LR_DEFAULTSIZE | LR_SHARED);
        wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName = NULL; /* メニュー名 */

        wc.lpszClassName = (LPCSTR)szClassName;
        /* hIconSmは16x16の小さいアイコンを指定します。 */
        wc.hIconSm = (HICON)LoadImage(NULL,
                MAKEINTRESOURCE(IDI_APPLICATION),       /* MAKEINTRESOURCE マクロ */
                IMAGE_ICON,
                0,
                0,
                LR_DEFAULTSIZE | LR_SHARED);
        /* ウィンドウ・クラスの登録に失敗したら終了する */
        if (!RegisterClassEx(&wc))
                return FALSE;
        
        /* ウィンドウの生成に失敗したら終了する */
        if (!InitInstance(hCurInst, nCmdShow)) 
                return FALSE;
        
        /* メッセージループ */
        while ((bResult = GetMessage(&msg, NULL, 0, 0)) != 0) {
                if (bResult == -1) {
                        break;
                } else {
                        TranslateMessage(&msg); /* 仮想キーメッセージを文字メッセージへ変換する。 */
                        DispatchMessage(&msg);  /* ウィンドウプロシージャへメッセージをディスパッチ(送出)する。 */
                }
        }
        return (int)msg.wParam;
}

/* ウィンドウの生成 */
BOOL InitInstance(HINSTANCE hInst, int nCmdShow)
{
        HWND hWnd;

        hWnd = CreateWindow(szClassName,        /* 登録されているクラス名 */
                szWindowsTitle,                                 /* ウィンドウ名(タイトルバーに表示されます) */
                WS_OVERLAPPEDWINDOW,                            /* ウィンドウの種類 */
                CW_USEDEFAULT,                                          /* ウィンドウの横方向の位置 */
                CW_USEDEFAULT,                                          /* ウィンドウの縦方向の位置 */
                CW_USEDEFAULT,                                          /* ウィンドウの幅 */
                CW_USEDEFAULT,                                          /* ウィンドウの高さ */
                NULL,                                                                   /* 親ウィンドウのハンドル */
                NULL,                                                                   /* メニューハンドル */
                hInst,                                                          /* アプリケーションインスタンスハンドル */
                NULL);
        if (!hWnd)
                return FALSE;
        ShowWindow(hWnd, nCmdShow);             /* ウィンドウを表示する。 */
        UpdateWindow(hWnd);                                     /* 更新リージョンが空ではない場合ウィンドウのクライアント領域を更新する */
        return TRUE;
}

/* ウィンドウプロシージャ */
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

        switch (msg) {

        case WM_CREATE:
                /* ボタンを配置する */
                CreateWindow("BUTTON", "てすと", WS_CHILD | WS_VISIBLE,
                   0, 0, 70, 70, hWnd, (HMENU)IDC_SDK_TEST1, hInst, NULL);
                
                CreateWindow("BUTTON", "てすと", WS_CHILD | WS_VISIBLE,
                  70, 0, 70, 70, hWnd, (HMENU)IDC_SDK_TEST2, hInst, NULL);
                
                connection_state = FALSE;
                break;

        case WM_COMMAND:
                switch (LOWORD(wParam)){
                case IDC_SDK_TEST1:
                        if ( connection_state ){
                                MessageBox(hWnd, "すでに接続されています", "確認", MB_OK);
                                break;
                        }
                        tDbname   = "??????"; /* ホスト文字列(??????部分は自分の環境で変えて下さい) */
                        tUsername = "??????"; /* ユーザー名(??????部分は自分の環境で変えて下さい) */
                        tPassword = "??????"; /* パスワード(??????部分は自分の環境で変えて下さい) */

                        connection_state = connect_oracle(hWnd, tUsername, tPassword, tDbname);
                        
                        break;
                case IDC_SDK_TEST2:
                        if ( !connection_state ){
                                break;
                        }       
                        connection_state = !rearrangement_oracle(hWnd);

                        break;
                }
                break;
        /*case WM_PAINT:
                break; */

        case WM_CLOSE:                                  /* 終了メッセージ */
                DestroyWindow(hWnd);
                break;

        case WM_DESTROY:                                /* ウインドウが破棄されているとき、送られます。 */
                if ( connection_state ){
                        rearrangement_oracle(hWnd);
                }
                PostQuitMessage(0);             /* 自らの終了を要求したことをシステムに伝えます。 */
                break;

        default:        /* アプリケーションが処理しないウィンドウメッセージに対して、既定の処理を提供します。 */
                return (DefWindowProc(hWnd, msg, wParam, lParam));/* デフォルトの処理 */
        }
        return 0;
}

/* 接続 */
BOOL connect_oracle(HWND hWnd, text *Username, text *Password, text *Dbname)
{
        BOOL bResult;
        sword swdOCILogon;

        /* 初期化 */
        OCIEnvCreate(&phOciEnv, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL);
        /* エラーハンドルの割り当て */
        OCIHandleAlloc(phOciEnv, (dvoid**)&phOciError, (ub4)OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
        /* OCILogon */
        swdOCILogon = OCILogon(phOciEnv, phOciError, &phOciSvcCtx, Username, strlen(Username), Password, strlen(Password), Dbname, strlen(Dbname));
        
        bResult = errprocessing(
                                                                        hWnd, 
                                                                        phOciError, 
                                                                        swdOCILogon
                                                                        );
        if (bResult){
                MessageBox(hWnd, "正常に接続されました", "接続状態", MB_OK);
                return TRUE;
        }else{
                MessageBox(hWnd, "接続失敗", "接続状態", MB_OK);
                return FALSE;
        }
}

/* 切断 */
BOOL rearrangement_oracle(HWND hWnd)
{
        BOOL bResult;

        /* OCILogoff */
        bResult = errprocessing(hWnd, phOciError, OCILogoff(phOciSvcCtx, phOciError));
        
        if (bResult){
                MessageBox(hWnd, "切断しました", "接続状態", MB_OK);
                bResult= TRUE;
        }else{
                bResult= FALSE;
        }

        /* エラーハンドルの解放 */
        OCIHandleFree(phOciError, OCI_HTYPE_ERROR);
        return bResult;
}

/* エラーをチェック */
static BOOL errprocessing(HWND hWnd, OCIError *phOciError, sword status)
{
        text errbuf[512];
        sb4 errcode = 0;
        /* oci.h 参照(oci.hを間違えて書き換えたりしないように注意) */    

        switch (status) {

        case OCI_SUCCESS:
                return TRUE;

        case OCI_INVALID_HANDLE:        /* -2 */
                MessageBox(hWnd, "OCI_INVALID_HANDLE", "エラー", MB_OK);
                return FALSE;

        case OCI_ERROR: /* -1 */
                OCIErrorGet(phOciError, 1, NULL, &errcode,
                        errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
                MessageBox(hWnd, errbuf, "エラー", MB_OK);
                return FALSE;

        case OCI_SUCCESS_WITH_INFO:     /* 1 */
                MessageBox(hWnd, "OCI_SUCCESS_WITH_INFO", "エラー", MB_OK);
                return FALSE;

        case OCI_NEED_DATA:             /* 99 */
                MessageBox(hWnd, "OCI_NEED_DATA", "エラー", MB_OK);
                return FALSE;

        case OCI_NO_DATA:       /* 100 */
                MessageBox(hWnd, "OCI_NO_DATA", "エラー", MB_OK);
                return FALSE;

        case OCI_STILL_EXECUTING:
                MessageBox(hWnd, "OCI_STILL_EXECUTE", "エラー", MB_OK);
                return FALSE;

        case OCI_CONTINUE:
                MessageBox(hWnd, "OCI_CONTINUE", "エラー", MB_OK);
                return FALSE;

        }
   
        return FALSE;
}

トップページ