非同期処理

OO4Oでは、非同期処理を使用して、SQL文とPL/SQLブロックを非ブロック・モードで実行できます。

非ブロック・モードは、CreateSQLメソッドのオプションです。

 

※ 詳細はヘルプファイルの「CreateSQLメソッド」と「非同期処理」を参照。

※ 非ブロック・モード = 非同期処理

1) 使用方法

Set orasqlstmt =oradatabase.CreateSQL(sql_statement,options)

2) 「options」について

ORASQL_NONBLK(値:&H4&)を指定する事により、非同期で動作します。

このオプションを使用すると、SQLを起動した後に直ちに制御はクライアント側に戻ってきます。

SQL文、又はPL/SQLはサーバー側で非同期で実行されています。

※ ここで言うSQLとはSQL文、ストアドプロシージャの事を示す。

3) OO4Oの制限事項

※ OO4Oヘルプファイルの「非ブロック化の制約」より

  1. OraSqlStmtオブジェクトで非ブロック操作を実行中の場合、
    このオブジェクトのプロパティまたは属性は変更できません。
    進行中の実行に影響を及ぼす可能性があるためです。
  2. すでにインスタンス化されている他のオブジェクトが接続上に存在する場合、
    OraSqlStmtを非ブロック・モードで作成することはできません。
  3. 非ブロック・コールの完了を待機している間、アプリケーションは
    このOraSqlStmtを含むOraDatabaseインスタンスでメソッドや
    プロパティを 起動することはできません。
    ※ これに関してOO4Oヘルプファイルから、回避方法が
    記載されているが、完全な方法とは思えない。

4)  標準化からの制限、約束事項

  1. 非同期処理に使うデータベースへの接続セッションは別途設ける。
    つまり、VBアプリは通常版と非同期専用版の2セッションをオープンする。
    1. 通常版 Oracle OO4Oオブジェクト変数
      Public poraSess     As OraSessionClass
      Public poraDb       As OraDatabase
    2. 非同期専用版 Oracle OO4Oオブジェクト変数
      Public poraSessW    As OraSessionClass
      Public poraDbW      As OraDatabase
      Public poraSQLW     As OraSqlStmt
  2. 非同期処理のSQLを起動後は、終了をタイマー監視しない。
    理由 : トラフィックを少なくなくす為。
  3. 非同期処理が完了したら、OraSqlStmtオブジェクト変数は開放する。
    理由 : そうしないとエラーが発生する場合がある。<-検証結果。
  4. ストアドプロシージャを起動する時は、ユーザーアカウントもバインド変数に与える。
    ストアドプロシージャでエラー発生時のログに使用する為。
  5. ストアドプロシージャでエラー発生時はエラーログを出力して終了処理を行う。
  6. 非同期の終了判定は、NonBlockingStateプロパティだけでなく、
    poraDbW.LastServerErr <> 0 かもチェックする。

 

非同期で動作させるストアドプロシージャの例

 

  ● 仕様部
  CREATE OR REPLACE PACKAGE SCOTT.PKG_TEST IS
   TYPE t_ename_tbl IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;
   TYPE t_job_tbl   IS TABLE OF VARCHAR2(9)  INDEX BY BINARY_INTEGER;
   PROCEDURE st_insert_delete(pc_name IN VARCHAR2,ename_tbl t_ename_tbl,
                              job_tbl t_job_tbl,i_count IN INTEGER);
  END PKG_TEST;

  ● 本体部
  CREATE OR REPLACE PACKAGE BODY SCOTT.PKG_TEST IS PROCEDURE
   st_insert_delete(pc_name IN VARCHAR2,ename_tbl t_ename_tbl,
                    job_tbl t_job_tbl,i_count INTEGER)
   IS
     i_index  INTEGER;
   BEGIN
     FOR i_index IN 1..i_count LOOP
       UPDATE BONUS SET job = job_tbl(i_index) , sal = i_index , comm = i_index
             WHERE ename = ename_tbl(i_index);
     END LOOP;
     COMMIT;
   EXCEPTION
     WHEN OTHERS THEN
        /* エラーログの出力 */
        RASE ・・・・・;
        ROLLBACK;
   END ST_INSERT_DELETE;
  END;

 

コーディング例

VBからSCOTTデータベースのBONUSテーブルを500件アップデートする。

処理は配列型バインド変数を利用してストアドプロシージャを起動し、非同期で実行される。

 

Private Sub cmd非同期ストアド起動_Click()
On Error GoTo Err_cmd非同期ストアド起動_Click:
    Dim strSql          As String           ‘SQL文編集変数
    Dim oraPAryEnameW   As OraParamArray    ‘オラクルの配列バインド変数
    Dim oraPAryJobW     As OraParamArray    ‘オラクルの配列バインド変数
    Dim lngRecCnt       As Long             ‘レコード件数
    Dim lngLoopIndex    As Long             ‘ルール変数
    Dim lngstat         As Long             ‘非同期SQLの状態変数





    ‘※事前に前回の非同期処理の終了状態を確認する
    ‘If OraSQLオブジェクトが存在する場合
    If Not (poraSQLW Is Nothing) Then
    ’NonBlockingStateプロパティは一端、Long型変数に入れる
        lngstat = poraSQLW.NonBlockingState ‘現在実行中のSQLの状態
        ‘SELECT ストアドプロシージャが
        Select Case lngstat
        Case ORASQL_STILL_EXECUTING         ‘Case 非同期で実行中の時
            MsgBox "以前、起動したストアドプロシージャは実行中です"
            Exit Sub
        Case Else ‘=ORASQL_SUCCESS      ‘(0) ‘Case 非同期で完了した時
            ‘正常終了してない場合
            If poraDbW.LastServerErr <> 0 Then
                ‘正常終了で無い場合はシステムエラーとする。    
                Call subErrSyori("tmr非同期ストアド起動_Timer", _
                    Err.Number, Err.Description)
            End If
            ‘必ず正常終了したらOraSQLオブジェクトを Nothing する
            Set poraSQLW = Nothing
        End Select
    End If

    lngRecCnt = 500
    ‘配列型バインド変数を定義をする
    With poraDbW.Parameters
        .Add "H_pcname", pstrComputerName, ORAPARM_INPUT
        .AddTable "H_ename", ORAPARM_INPUT, ORATYPE_VARCHAR2, lngRecCnt, 10
        .AddTable "H_job", ORAPARM_INPUT, ORATYPE_VARCHAR2, lngRecCnt, 9
        ‘ストアドプロシージャへ配列の件数データもセットする
        .Add "H_count", lngRecCnt, ORAPARM_INPUT
    End With

    ‘パラメータのデータ型を指定する
    With poraDbW
        .Parameters("H_count").serverType = ORATYPE_NUMBER
    End With

    ‘配列型バインド変数オブジェクトを作成する
    With poraDbW
        Set oraPAryEnameW = .Parameters("H_ename")
        Set oraPAryJobW = .Parameters("H_job")
    End With

    ‘配列型バインド変数オブジェクトに値をセットする
    ‘注)配列の添え字はゼロから
    For lngLoopIndex = 0 To (lngRecCnt – 1)     
        oraPAryEnameW.put_Value Format$(lngLoopIndex + 1, "0000000000"), lngLoopIndex
        oraPAryJobW.put_Value "仕事" & Format$(lngLoopIndex + 1, "0000"), lngLoopIndex
    Next lngLoopIndex

    ‘配列型バインド変数のサーバーのストアドプロシージャで非同期に実行する
    strSql = "BEGIN PKG_TEST.st_insert_delete(:H_pcname,:H_ename,:H_job,:H_count); END;"

    ‘事前に必ずOraSQLオブジェクトを Nothing する。注)こうしないとエラーが出るときがある
    Set poraSQLW = Nothing
    ‘SQLを非ブロック状態で実行する
    Set poraSQLW = poraDbW.CreateSql(strSql, ORASQL_NONBLK)

    ‘非同期の起動でエラーがあればここでエラーが帰る
    If poraDbW.LastServerErr <> 0 Then
        Call subErrSyori("cmd非同期ストアド起動_Click", _
             Err.Number, Err.Description)
    End If

    ‘パラメータ定義を開放する
    With poraDbW.Parameters
        .Remove "H_pcname"
        .Remove "H_ename"
        .Remove "H_job"
        .Remove "H_count"
    End With

    Exit Sub

Err_cmd非同期ストアド起動_Click:
    ‘ランタイムエラーが発生したのでエラー処理をする
    Call subErrSyori("cmd非同期ストアド起動_Click", Err.Number, Err.Description)
End Sub

 

 

OO4Oコーディング標準(VB)

初期登録日: 2003年11月12日

最終更新日: 2008年01月26日

< Home ヘ戻る >


キーボード

ブラウザ画面の文字サイズを変更するショートカットキー

  1. [ CTRL ] + [ + ]  :  文字を大きく
  2. [ CTRL ] + [ ]  :  文字を小さく

Shortcut Keys

  1. [ CTRL ] + [ + ]  :  Up the font size
  2. [ CTRL ] + [ ]  :  Down the font size