ヘッダーをスキップ
Oracle® Objects for OLE開発者ガイド
11gリリース2 (11.2) for Microsoft Windows
B58887-04
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

3 基本的な機能

この章では、Oracle Objects for OLEの基本的な機能について説明します。

内容は次のとおりです。

クライアント・アプリケーションの概要

Oracle Objects for OLEを使用すると、クライアント・アプリケーションでは、Oracleデータベースに接続して各種コマンドを実行し、戻された結果にアクセスして操作できます。特定のタスクの実行順序には多少の柔軟性はありますが、OO4Oのオートメーション・オブジェクトを使用する各アプリケーションでは、次の基本的な手順を実行します。

Oracle Objects for OLEオートメーション・サーバーへのアクセス

OO4Oオートメーション・サーバーを使用してOracleデータベースに接続するには、最初にサーバーのインスタンスを作成する必要があります。Visual Basic(VB)の場合、NEWキーワードを使用することもできますが、通常はCreateObjectメソッドをコールすることでインスタンスを作成します。

Visual BasicのCreateObjectメソッドは、次の2つのOO4Oサーバー・オブジェクトとともに使用できます。次のいずれかのオブジェクトのインタフェースによって、OO4Oへのアクセスが提供され、Oracle Databaseへの接続が可能になります。

  • OraSession

    アプリケーションの最高レベルのオブジェクトです。これは、OraDatabaseOraConnectionおよびOraDynasetオブジェクトのコレクションを管理します。

  • OraServer

    データベース・インスタンスへの物理的な接続を表し、接続多重化の使用が可能になります。

CreateObjectメソッドは、コンポーネントとオブジェクトのIDを引数として使用します。

OraSessionオブジェクトの取得

次のスクリプトでは、Visual BasicでのOraSessionオブジェクトの取得方法を示します。OO4OSessionは、OraSessionオブジェクトのインスタンスを保持するオブジェクト変数です。

Dim OO4OSession as Object 
Set OO4OSession = CreateObject(“OracleInProcServer.XOraSession") 

または

Dim OO4OSession as OraSession 
Set OO4OSession = New OraSessionClass 

または

Dim OO4OSession as New OraSessionClass 

次の例では、IIS Active Server PagesでのOraSessionオブジェクトの取得方法を示します。

<OBJECT RUNAT=Server SCOPE=APPLICATION ID=OO4OSession
                PROGID="OracleInProcServer.XOraSession"> 
</OBJECT> 

OracleInProcServer.XOraSessionは、Oracleクライアント・インストール・プログラムがWindowsレジストリに登録する、バージョンに依存しないOO4OのプログラムIDです。これは、OO4Oコンポーネントを識別するグローバル一意識別子(CLSID)のシンボリック名です。

OraServerオブジェクトの取得

OO4Oオートメーション・サーバーへのアクセスには、OraServerオブジェクトのインタフェースも使用できます。

Dim OO4OServer as Object 
Set OO4OServer = CreateObject("OracleInProcServer.XOraServer") 

これで、Oracle Databaseに接続できます。

Oracle Databaseへの接続

インタフェースを取得した後は、そのインタフェースを使用してOpenDatabaseメソッドをコールし、Oracleデータベースにユーザー・セッションを確立できます。

Set EmpDb= OO4OSession.OpenDatabase("ExampleDb", "Scott/Tiger", 0) 

または

Set EmpDb= OO4OServer.OpenDatabase("Scott/Tiger") 

変数EmpDbはユーザー・セッションを表します。これはOraDatabaseインタフェースを保持し、ネットワーク接続別名にExampleDbを使用し、ユーザー名とパスワードにscott/tigerを使用して、Oracle Databaseにコマンドを送信します。


関連項目:

OpenDatabaseメソッド

OraServerを使用した接続多重化

OraServerインタフェースを使用すると、複数のユーザー・セッションでデータベースへの物理的なネットワーク接続を共有できます。これによって、ネットワークとデータベースのリソース使用量が削減されるため、サーバーの拡張性が向上します。ただし、複数のユーザー・セッションによるコマンド実行は、接続上でシリアル化されます。したがって、この機能は、パフォーマンス上の理由からコマンドのパラレル実行が必要なマルチスレッド・アプリケーションで使用することはお薦めしません。

次のコード例では、OraServerインタフェースを使用して2つのユーザー・セッションを確立する方法を示します。

Set OO4OServer = CreateObject("OracleInProcServer.XOraServer") 
OO4OServer.Open("ExampleDb") 
Set EmpDb1 = OO4OServer.OpenDatabase("Scott/Tiger") 
Set EmpDb2 = OO4OServer.OpenDatabase("Scott/Tiger") 

ユーザー・セッションは、以前に作成したオブジェクトのプールから取得することもできます。

各種コマンドの実行

OO4Oオートメーション・オブジェクトを使用して、Oracleデータベースに送信できるコマンドは、次のカテゴリに分類されます。

問合せ

問合せとは、データベースからデータを取り出す文です。1つの問合せで、0行、1行または複数行のデータを戻すことができます。すべての問合せは、次の例のようにSQLキーワードのSELECTで始まります。

SELECT ename, empno FROM emp 

OO4Oでは、このようなSELECT文は、OraDatabaseインタフェースのCreateDynasetメソッドと一緒に使用されることで問合せを実行します。このメソッドは、戻された行セットにアクセスして操作するために使用されるOraDynasetオブジェクトを戻します。OraDynasetオブジェクトは、実行した問合せによって戻された行セットの参照を可能にする、(前方および後方に)スクロール可能なクライアント側カーソルの機能をカプセル化します。


注意:

後方へのスクロールが不要な場合は、クライアントのローカル・ディスクにおける結果セットのキャッシュを使用禁止にできます。パフォーマンスの大幅な向上につながるため使用禁止にすることをお薦めします。CreateDynasetメソッドにORADYN_NOCACHEオプションを渡すと、キャッシュが使用禁止になります。この定数は、oraconst.txtファイルに定義されており、OO4Oがインストールされているルート・ディレクトリORACLE_BASE\\ORACLE_HOME\OO4Oにあります。

次のコード例では、ExampleDbデータベースに接続して問合せを実行し、行の結果セットを移動して、単純なメッセージ・ボックスに各行の列値を表示する方法を示します。

Set OO4OSession = CreateObject(“OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("ExampleDb", "Scott/Tiger", 0 ) 
 
' SELECT query described above used in next line 
Set Employees = EmpDb.CreateDynaset("SELECT ename, empno FROM" & _ 
          "emp",ORADYN_NOCACHE) 
While NOT Employees.EOF 
  MsgBox "Name: " & Employees("ENAME").value & "Employee #: " & _
          Employees("EMPNO").value 
Employees.MoveNext 
Wend 

この例にあるEmployees("ENAME")とEmployees("EMPNO")は、結果セットの現在の行からENAME列とEMPNO列の値をそれぞれ戻します。列値にアクセスする他の方法は、ENAME列にEmployees(0)EMPNO列にEmployee(1)のように、列の位置を使用する方法です。この方法によって、名前で列を参照するよりも速く列の値を取得できます。

この例のEmployees.MoveNext文は、結果セットの現在の行を次の行に設定します。結果セットの最終行より後ろに移動しようとすると、OraDynasetEOFプロパティがTRUEに設定されます。

MoveNextメソッドは、OraDynasetインタフェース内のナビゲーショナル・メソッドの1つです。ナビゲーショナル・メソッドには、MoveFirstMoveLastMoveNextMovePreviousMoveNextnMovePreviousnMoveRelおよびMoveToがあります。

OraDynasetオブジェクトは、更新可能な実表またはビューから取り出した行を更新および削除するメソッドも提供しています。さらに、新しい行を挿入する方法も提供しています。「OraDynasetオブジェクト」を参照してください。

問合せでは、次の例のように、入力(バインド)変数を使用して、データベースにデータを提供するプログラムも要求できます。

SELECT name, empno 
        FROM employees 
        WHERE ename = :ENAME

このSQL文で、:ENAMEはアプリケーションが提供する変数のプレースホルダです。

OO4Oでは、OraParameterオブジェクトを使用して、プレースホルダにデータ値を提供します。

パラメータを定義するには、OraParametersコレクション・オブジェクトを使用します。このオブジェクトは、OraDatabaseインタフェースのParametersプロパティを参照することによって取得します。OraParametersコレクションは、OraParameterオブジェクトへの参照を追加、削除および取得するためのメソッドを提供します。

次の文は、EmpDbオブジェクト内のOraParametersコレクションに入力パラメータのORAPARM_INPUTを追加します。

EmpDb.Parameters.Add "ENAME", "JONES", ORAPARM_INPUT 

ENAMEはパラメータ名で、SQL文のプレースホルダの名前と同じ(前述のサンプル・コードの:ENAME)であることが必要です。初期値としてJONESが指定され、ORAPARM_INPUTINPUTパラメータとして使用されたことをOO4Oに通知します。

次の例では、'JONES'という名前の従業員を含んだ1行のみのOraDynasetオブジェクトを作成します。

Set OO4OSession = CreateObject(“OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("ExampleDb", "Scott/Tiger", 0 ) 
EmpDb.Parameters.Add "ENAME", "JONES", ORAPARM_INPUT 
Set Employees = EmpDb.CreateDynaset("SELECT ename, empno FROM emp" & _
           "WHERE ename = :ENAME",ORADYN_NOCACHE) 

While NOT Employees.EOF 
   MsgBox "Name: " & Employees("ename").value & "Employee #: " & _
            Employees("empno").value 
   Employees.MoveNext 
Wend 

データ操作言語文

データ操作言語(DML)文では、データベース表のデータを変更できます。たとえば、次のような操作にDML文が使用されます。

OO4OのOraDatabaseインタフェースは、DML文を実行するための2つのメソッド、ExecuteSQLCreateSQLを提供します。次の説明には、これらのメソッドを様々なタイプのDML文の実行に使用する方法が記載されています。

データベース・レコードの更新

次の例では、ExecuteSQLメソッドを使用してUPDATE文を実行します。

Set OO4OSession = CreateObject("OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("ExampleDb", "scott/tiger", 0) 
EmpDb.Parameters.Add "ENAME", "JONES", ORAPARM_INPUT 
EmpDb.ExecuteSQL ("UPDATE emp SET sal = sal + 1000 WHERE ename = :ENAME") 

UPDATE文の実行には、CreateSQLメソッドを使用する方法もあります。

Set sqlStatement = EmpDb.CreateSQL("UPDATE emp SET sal = sal + 1000" & _ 
             "WHERE ename = :ENAME", 0&) 

ExecuteSQLCreateSQLメソッドは両方とも、提供されたUPDATE文を実行します。異なる点は、CreateSQLメソッドでは文の実行に加えOraSQLStmtインタフェースへの参照を戻すことです。このインタフェースは、後でRefreshメソッドを使用して同じ問合せを実行するときに使用できます。この問合せはすでにデータベースで解析されているため、後に続く同じ問合せの実行が、特にバインド・パラメータを使用した場合に高速化されます。

たとえば、名前がKINGという従業員の給与を1000増加するには、プレースホルダの値を変更し、sqlStatementオブジェクトを次のようにリフレッシュします。

EmpDb.Parameters("ENAME").Value = "KING" sqlStatement.Refresh 

頻繁に実行されるDML文の場合は、ExecuteSql文を反復して使用するよりも、OraSqlStmtオブジェクトにパラメータを使用する方が効率的です。OraSQLStmtRefreshメソッドが実行されると、データベースによる文の解析は不要になります。異なるパラメータ値を持つ同じ問合せが頻繁に実行される、Webサーバーなどのアプリケーション・サーバーでは、前述の方法によってOracle Databaseの処理を大幅に軽減できます。

表からの行の削除

次の例では、CreateSQLメソッドを使用してemp表から行を削除します。

Set OO4OSession = CreateObject("OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("ExampleDb", "scott/tiger", 0) 
EmpDb.Parameters.Add "ENAME", "JONES", ORAPARM_INPUT 
Set sqlStatement = EmpDb.CreateSQL ("DELETE from emp WHERE ename = :ENAME")

emp表から別の行を削除するには、パラメータの値を変更してsqlStatementオブジェクトをリフレッシュします。

EmpDb.Parameters("ENAME").Value = "KING" sqlStatement.Refresh 

表への新しい行の挿入

次の例では、表に新しい行を追加します。

Set OO4OSession = CreateObject("OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("ExampleDb", "scott/tiger", 0) 
EmpDb.ExecuteSQL ("INSERT INTO emp (empno, ename, job, mgr, deptno)" & _ 
           "VALUES (1233,'OERTEL', 'WRITER', 7839, 30) ") 

パラメータ配列を使用した複数行の挿入

パラメータ配列を使用すると、表内の複数行をフェッチ、更新、挿入または削除できます。パラメータ配列を使用した複数行の操作は、行を個別に操作する文を複数回にわたって実行するより効率的です。

次の例では、パラメータ配列の作成にOraDatabaseインタフェースのAddTableメソッドを使用する方法を示します。配列には値が移入されており、emp表に2つの行を挿入するINSERT文の実行ではプレースホルダとして使用されます。

Set OO4OSession = CreateObject("OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("Exampledb", "scott/tiger", 0) 
 
'Creates parameter arrays for the empno, ename, job, and salary columns 
EmpDb.Parameters.AddTable "EMPNO_ARRAY", ORAPARM_INPUT, ORATYPE_NUMBER, 2
EmpDb.Parameters.AddTable "ENAME_ARRAY", ORAPARM_INPUT, ORATYPE_VARCHAR2, 2, 10
EmpDb.Parameters.AddTable "JOB_ARRAY", ORAPARM_INPUT, ORATYPE_VARCHAR2, 2, 9
EmpDb.Parameters.AddTable "MGR_ARRAY", ORAPARM_INPUT, ORATYPE_NUMBER, 2
EmpDb.Parameters.AddTable "DEPT_ARRAY", ORAPARM_INPUT, ORATYPE_VARCHAR2, 2, 10
Set EmpnoArray = EmpDb.Parameters("EMPNO_ARRAY") 
Set EnameArray = EmpDb.Parameters("ENAME_ARRAY") 
Set JobArray = EmpDb.Parameters("JOB_ARRAY") 
Set MgrArray = EmpDb.Parameters("MGR_ARRAY") 
Set DeptArray = EmpDb.Parameters("DEPT_ARRAY") 
 
'Populate the arrays with values 
EmpnoArray(0) = 1234 
EnameArray(0) = "JORDAN" 
JobArray(0) = "SALESMAN" 
MgrArray(0) = 7839 
DeptArray(0) = 30 
EmpnoArray(1) = 1235 
EnameArray(1) = "YOUNG" 
JobArray(1) = "SALESMAN" 
MgrArray(1) = 7839 
DeptArray(1) = 30 
 
'Insert two rows 
EmpDb.ExecuteSQL ("INSERT INTO emp (empno, ename, job, mgr, deptno) VALUES" & _ 
          "(:EMPNO_ARRAY,:ENAME_ARRAY, :JOB_ARRAY,:MGR_ARRAY, :DEPT_ARRAY)") 

関連項目:

AddTableメソッド

スレッド・セーフティ

OO4Oはスレッド・セーフであるため、マルチスレッドのアプリケーションおよびMicrosoft Internet Information Server(IIS)などの環境で効果的に使用できます。OO4Oは、COM/DCOM環境でのフリー・スレッドとアパートメント・スレッドの両モデルをサポートします。

OO4Oオブジェクト属性へのアクセスは、複数のスレッドを使用して実行されるとシリアル化されます。マルチスレッド・アプリケーションでの問合せ実行で最大の並列性をOO4Oで達成するには、複数スレッドでのオブジェクト共有を回避してください。

複数のスレッド間で共有されているセッション・オブジェクトで、コミット操作およびロールバック操作を使用することを避けてください(そのセッションと関連付けられているすべての接続がコミットまたはロールバックされるため)。セッション・オブジェクトでコミット操作およびロールバック操作を実行するには、使用するデータベース・オブジェクトごとに一意のセッション・オブジェクトを作成します。

接続プール管理機能の使用

OO4Oの接続プールは、OraDatabaseオブジェクトのプールです。OO4Oの接続プールは、(多くの場合)すでに接続しているOraDatabaseオブジェクトのグループです。データベースとの間で接続と切断を繰り返す必要のあるアプリケーション(ASP Webアプリケーションなど)の場合は、接続プールを使用するとパフォーマンスが向上します。

接続プールの作成

接続プールは、OraSessionインタフェースのCreateDatabasePoolメソッドをコールすることによって作成されます。OraDatabaseオブジェクトは、Oracleデータベースへの接続を表し、SQL文とPL/SQLブロックを実行するためのメソッドを含んでいます。

プールからのオブジェクトの取得と返却

プールからOraDatabaseオブジェクトを取リ出すには、GetDatabaseFromPoolメソッドをコールします。このファンクションは、OraDatabaseオブジェクトへの参照を戻します。

プールの破棄

プールが属している親セッション・オブジェクトが破棄されると、そのプールも暗黙的に破棄されます。DestroyDatabasePoolメソッドをコールすることにより、いつでも明示的に破棄できます。

プール属性へのアクセス

データベース・プールのプロパティは、次のとおりです。これらのプロパティは読取り専用です。

  • DbPoolMaxSize - 最大プール・サイズ

  • DbPoolCurrentSize - プールの現在のサイズ

  • DbPoolInitialSize - プールの初期サイズ

接続プールのデータベースを使用したトランザクション処理

次の例では、推奨するトランザクションの処理方法を示します。

set Odb = OraSession.GetDatabaseFromPool(0) 
Odb.Connection.BeginTrans 
… 
 
Odb.Connection.CommitTrans 

失われた接続の検出

リリース8.1.6以上のクライアントにリンクされたOO4Oは、失われた接続の検出をサポートします。

OraDatabaseオブジェクトのConnectionOKプロパティをコールすることで、データベース接続の状態をアプリケーションで検証できます。OraSession.GetDatabaseFromPoolメソッドは、アプリケーションにOraDatabaseを戻す前に、接続を検証するようになりました。

接続が失われている場合、GetDatabaseFromPoolメソッドはその接続を削除し、新しい接続をフェッチします。

Dim MyDatabase As OraDatabase 
Set MySession = CreateObject("OracleInProcServer.XOraSession") 
Set MyDatabase = MySession.OpenDatabase("ora90", "scott/tiger", 0&) 
 
' Other code 
...
' Check if the database connection has not timed out 
if MyDatabase.ConnectionOK 
  MsgBox " The database connection is valid" 
endif 

PL/SQLのサポート

PL/SQLは、SQLを拡張したOracleの手続き型言語です。PL/SQLは、単純な問合せやSQLのデータ操作言語文では実行できない複雑なタスクを処理します。PL/SQLがない場合、Oracle Databaseでは、SQL文を1回に1文ずつ処理する必要があります。各SQL文ではデータベースに対して別のコールが発生するため、パフォーマンス上のオーバーヘッドが高くなります。ネットワーク環境では、このオーバーヘッドが大きな負担となる可能性があります。SQL文が発行されるたびに、ネットワークを介してSQL文を送信する必要があるため、通信量が増加します。PL/SQLでは、複数文のブロック全体をデータベースに1回で送信できます。これによって、アプリケーションとデータベース間での通信量を大幅に削減できます。

PL/SQLでは、多数の構造体を1ブロックにグループ化し、1つの単位として実行できます。次の内容が含まれています。

  • 1つ以上のSQL文

  • 変数宣言

  • 代入文

  • プロシージャ制御文(IF...THEN...ELSE文とループ)

  • 例外処理文

  • 他のOracleのストアド・プロシージャとストアド・ファンクションへのコール

  • レコード、表およびカーソルのFORループなどの特別なPL/SQL機能

  • カーソル変数

PL/SQLのOracle Objects for OLEとの統合

Oracle Objects for OLE(OO4O)は、PL/SQLのストアド・プロシージャとの緊密な統合を提供します。OO4Oは、PL/SQLストアド・プロシージャ、PL/SQL表およびPL/SQLカーソルなどをサポートします。PL/SQLバインド変数は、OraParameterAddメソッドを介してサポートされます。

ストアド・プロシージャ・ブロックは、CreateSQLメソッドまたはExecuteSQLメソッドのいずれかを使用して実行されます。

Oracle Objects for OLEは、ストアド・プロシージャまたはPL/SQLの無名ブロックで作成されたカーソルを、READONLYダイナセット・オブジェクトとして戻すことができます。このためには、カーソル変数をORATYPE_CURSOR型のOraParameterオブジェクトとして割り当てる必要があります。

ストアド・プロシージャを実行した後、このOraParameterオブジェクトのValueプロパティは、読取り専用のダイナセット・オブジェクトを戻します。

このダイナセット・オブジェクトは、他のダイナセット・オブジェクトと同様に処理できます。

ExecuteSQLとCreateSQLを使用したPL/SQLブロックの実行

OO4Oでは、次の例に示すように、OraDatabaseオブジェクトのExecuteSQLまたはCreateSQLメソッドを使用して、PL/SQLブロックを実行できます。

Set OO4OSession = CreateObject("OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("ExampleDb", "scott/tiger", 0) 
 
'Add EMPNO as an Input parameter and set its initial value. 
EmpDb.Parameters.Add "EMPNO", 7369, ORAPARM_INPUT 
EmpDb.Parameters("EMPNO").ServerType = ORATYPE_NUMBER 
 
'Add ENAME as an Output parameter and set its initial value. 
EmpDb.Parameters.Add "ENAME", 0, ORAPARM_OUTPUT 
EmpDb.Parameters("ENAME").ServerType = ORATYPE_VARCHAR2 
 
'Add SAL as an Output parameter 
EmpDb.Parameters.Add "SAL", 0, ORAPARM_OUTPUT 
EmpDb.Parameters("SAL").ServerType = ORATYPE_NUMBER 
 
'Add COMMISSION as an Output parameter and set its initial value. 
EmpDb.Parameters.Add "COMMISSION", 0, ORAPARM_OUTPUT 
EmpDb.Parameters("COMMISSION").ServerType = ORATYPE_NUMBER 
EmpDb.ExecuteSQL ("BEGIN SELECT ename, sal, comm INTO :ENAME, :SAL," & _ 
             ":COMMISSION FROM emp WHERE empno = :EMPNO; END;") 
 
'display the values of Ename, Sal, Commission parameters 
MsgBox "Name: " & EmpDb.Parameters("ENAME").Value 
MsgBox "Salary " & EmpDb.Parameters("SAL").Value 
MsgBox "Commission: " & EmpDb.Parameters("COMMISSION").Value 

次の例では、OO4OのCreateSQLメソッドを使用してストアド・プロシージャをコールするPL/SQLブロックを実行します。このプロシージャは、入力情報として部門番号を使用し、部門の名前と所在地を戻します。

この例は、従業員データベースにストアド・プロシージャを作成するために使用されます。

CREATE OR REPLACE PACKAGE Department as 
PROCEDURE GetDeptName (inDeptNo IN NUMBER, outDeptName OUT VARCHAR2, 
                   outDeptLoc OUT VARCHAR2); 
END Department;
/
 
CREATE OR REPLACE PACKAGE BODY Department as 
PROCEDURE GetDeptName(inDeptNo IN NUMBER, outDeptName OUT VARCHAR2, 
                 outDeptLoc OUT VARCHAR2) is 
BEGIN 
   SELECT dname, loc into outDeptName, outDeptLoc from DEPT 
      WHERE deptno = inDeptNo; 
   END; 
END Department;
/ 

次の例では、前述のプロシージャを実行して、deptno10である部門の名前と所在地を取得します。

Set OO4OSession = CreateObject("OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("ExampleDb", "scott/tiger", 0) 
empDb.Parameters.Add "DEPTNO", 10, ORAPARM_INPUT 
empDb.Parameters("DEPTNO").ServerType = ORATYPE_NUMBER 
empDb.Parameters.Add "DNAME", 0, ORAPARM_OUTPUT 
empDb.Parameters("DNAME").ServerType = ORATYPE_VARCHAR2 
empDb.Parameters.Add "DLOC", 0, ORAPARM_OUTPUT 
empDb.Parameters("DLOC").ServerType = ORATYPE_VARCHAR2 
Set PlSqlStmt = empDb.CreateSQL("Begin Department.GetDeptname" & _ 
             "(:DEPTNO, :DNAME, :DLOC); end;", 0&) 
 
'Display Department name and location 
MsgBox empDb.Parameters("DNAME").Value & empDb.Parameters("DLOC").Value 

PL/SQLカーソル変数を戻す方法

PL/SQLカーソル変数は主に、PL/SQLブロックからの1つ以上の問合せ結果セット、ストアド・プロシージャおよびファンクションにアクセスするために使用されます。OO4OのOraParameterオブジェクトは、PL/SQLカーソル変数を保持するために使用できます。

カーソル変数を表すOraParameterオブジェクトは、ORATYPE_CURSOR型である必要があり、出力変数としてのみ定義できます。PL/SQLブロックを実行した後、OraParameterオブジェクトのValueプロパティには、読取り専用のOraDynasetオブジェクトが含まれます。このOraDynasetオブジェクトを使用すると、戻された行をスクロールできます。

場合によっては、PL/SQLプロシージャの実行には、ExecuteSQLメソッドよりもCreateSQLメソッドの使用が適切です。OraSQLStmtオブジェクトのRefreshメソッドを実行すると、PL/SQLカーソルの状態が変化する場合があります。CreateSQLメソッドを使用した場合、変化したカーソルは既存のダイナセット・オブジェクトに自動的に関連付けられ、新しいダイナセット・オブジェクトは作成されません。

ダイナセット・オブジェクトのSQLプロパティは設定できません。設定しようとするとエラーになります。


注意:

テーブル・パラメータとしてカーソルを含んだPL/SQLストアド・プロシージャはサポートされていません。

パラメータ・オブジェクトのRemoveメソッドをコールしてください。このメソッドは、ダイナセット・オブジェクトおよびローカル一時キャッシュ・ファイルの廃棄に便利です。

次の例では、empdept表のカーソルを取得するストアド・プロシージャとこのプロシージャを実行する小規模なアプリケーションを示します。

ストアド・プロシージャ

CREATE PACKAGE EmpAndDept AS
   cursor emp is select * from emp;
   cursor dept is select * from dept;
   TYPE EmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE;
   TYPE DeptCurTyp IS REF CURSOR RETURN dept%ROWTYPE;
   PROCEDURE GetEmpAndDeptData (emp_cv OUT EmpCurTyp, 
                              dept_cv OUT DeptCurTyp);
END EmpAndDept;/
 
 
CREATE PACKAGE BODY EmpAndDept AS
   PROCEDURE GetEmpAndDeptData (emp_cv OUT EmpCurTyp, 
                                dept_cv OUT DeptCurTyp) IS
       BEGIN 
         OPEN emp_cv FOR SELECT * FROM emp;
         OPEN dept_cv FOR SELECT * FROM dept; END GetEmpAndDeptData;
END EmpAndDept;
/

アプリケーション

Set OO4OSession = CreateObject("OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("ExampleDb", "scott/tiger", 0) 
empDb.Parameters.Add "EMPCUR", 0, ORAPARM_OUTPUT 
empDb.Parameters("EMPCUR").serverType = ORATYPE_CURSOR 
empDb.Parameters.Add "DEPTCUR", 0, ORAPARM_OUTPUT 
empDb.Parameters("DEPTCUR").serverType = ORATYPE_CURSOR 
Set PlSqlStmt = empDb.CreateSql("Begin EmpAndDept.GetEmpAndDeptData (:EMPCUR," & _
             ":DEPTCUR); end;", 0) 
Set EmpDynaset = empDb.Parameters("EmpCur").Value 
Set DeptDynaset = empDb.Parameters("DeptCur").Value 
MsgBox EmpDynaset.Fields("ENAME").Value 
MsgBox DeptDynaset.Fields("DNAME").Value 

PL/SQL表を戻す方法

PL/SQL表は、主としてPL/SQLデータの配列にアクセスするために使用されます。OO4OのOraParamArrayオブジェクトは、PL/SQLカーソル変数を保持するために使用できます。

表の変数を表すOraParamArrayオブジェクトは、AddTableメソッドを使用して最初に作成する必要があります。表の値は、OraParamArrayオブジェクトのGet_ValuePut_Valueメソッドを使用して、アクセスまたは設定します。

PL/SQLプロシージャのGetEmpNamesInArrayは、EMPNOの配列に対するENAME値の配列を戻します。

CREATE PACKAGE EmpNames AS 
    type NUMARRAY is table of NUMBER index by 
          BINARY_INTEGER; --Define EMPNOS array 
    type VCHAR2ARRAY is table of VARCHAR2(10) index by 
          BINARY_INTEGER; --Define ENAMES array 
    PROCEDURE GetEmpNamesInArray (ArraySize IN INTEGER, 
              inEmpnos IN NUMARRAY, outEmpNames OUT VCHAR2ARRAY); 
END EmpNames; /
 
 
CREATE PACKAGE BODY EmpNames AS 
    PROCEDURE GetEmpNamesInArray (ArraySize IN INTEGER, 
              inEmpnos IN NUMARRAY, outEmpNames OUT VCHAR2ARRAY) is 
    BEGIN 
    FOR I in 1..ArraySize loop 
        SELECT ENAME into outEmpNames(I) from EMP 
                       WHERE EMPNO = inEmpNos(I); 
    END LOOP; 
END; 
 
END EmpNames; /
 

次の例では、前述のプロシージャを実行してename表を取得します。

Set OO4OSession = CreateObject("OracleInProcServer.XOraSession") 
Set Empdb = OO4OSession.OpenDatabase("Exampledb", "scott/tiger", 0) 
Empdb.Parameters.Add "ArraySize", 3, ORAPARM_INPUT 
Empdb.Parameters.AddTable "EMPNOS", ORAPARM_INPUT, ORATYPE_NUMBER, 3, 22 
Empdb.Parameters.AddTable "ENAMES", ORAPARM_OUTPUT, ORATYPE_VARCHAR2, 3, 10
Set EmpnoArray = Empdb.Parameters("EMPNOS") 
Set EnameArray = Empdb.Parameters("ENAMES") 
 
'Initialize the newly created input parameter table EMPNOS 
EmpnoArray(0) = 7698 
EmpnoArray(1) = 7782 
EmpnoArray(2) = 7654 
Empdb.ExecuteSQL ("Begin EmpNames.GetEmpNamesInArray(:ArraySize," & _ 
              ":EMPNOS, :ENAMES); End;") 
MsgBox EnameArray(0) 
MsgBox EnameArray(1) 
MsgBox EnameArray(2) 

データ定義言語文の実行

データ定義言語(DDL)文は、データベースのスキーマ・オブジェクトを管理します。DDL文は、新しい表の作成、古い表の削除、および他のスキーマ・オブジェクトの確立を実行します。また、スキーマ・オブジェクトへのアクセスも制御します。次に、例を示します。

Set OO4OSession = CreateObject("OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("ExampleDb", "scott/tiger", 0) 
EmpDb.ExecuteSQL("create table employees (name VARCHAR2(20)," & _
          "ssn VARCHAR2(12), empno NUMBER(6), mgr NUMBER(6), salary NUMBER(6)") 

EmpDb.ExecuteSQL("GRANT UPDATE, INSERT, DELETE ON employees TO donna") 
EmpDb.ExecuteSQL("REVOKE UPDATE ON employees FROM jamie") 

DDL文を使用すると、Oracle Databaseのオブジェクトも処理できます。次に例を示します。

Set OO4OSession = CreateObject("OracleInProcServer.XOraSession") 
Set EmpDb = OO4OSession.OpenDatabase("ExampleDb", "scott/tiger", 0)  
EmpDb.ExecuteSQL("create type person_t as object (name VARCHAR2(30)," & _
             "ssn VARCHAR2(12),address VARCHAR2(50))") 
EmpDb.ExecuteSQL("create table person_tab OF person_t") 

トランザクション制御

トランザクションは論理的な作業単位で、1人のユーザーが実行する1つ以上のSQL文で構成されています。一般的な例は、ある銀行口座から別の銀行口座への送金です。これには2つの操作が発生します。

  1. 口座から金額が引き落とされます。

  2. 別の口座にその金額が入金されます。

この2つの操作は一緒に実行する必要があります。(ネットワークの接続故障などで)片方の操作が実行され、他方の操作が実行されないと、銀行帳簿は正しく貸借一致しません。

通常、ダイナセットでUpdateメソッドを実行すると、変更内容はデータベースにただちにコミットされます。各操作は個別のトランザクションとして扱われます。OraSessionオブジェクトのBeginTransCommitTransおよびRollbackトランザクション制御メソッドを使用すると、複数の操作を1つの大きいトランザクションにグループ化できます。

BeginTransメソッドは、操作グループの開始をセッションに通知します。CommitTransメソッドは、操作グループ全体を確定します。Rollbackメソッドは、グループ全体を取り消します。CommitTransおよびRollbackメソッドがトランザクションを終了すると、プログラムは1つの操作につき1つのトランザクションという通常の操作に戻ります。経験のあるOracle Databaseユーザーは、次に示すOracle Objects for OLEの操作とOracle Databaseのツール製品との違いに注意してください。

  • SQL*PlusなどのOracle Databaseのツール製品は、そのツールの起動時にBeginTransメソッドがコールされたものとして実行されます。これは、更新はただちにはコミットされず、コミットまたはロールバックの実行まで保留されることを意味します。

  • SQL*Plusは、コミットまたはロールバックが実行されるたびに、新しいトランザクションを開始します。

  • UPDATEまたはDELETE文に失敗した場合、SQL*Plusは行をロックしません。ただし、OO4Oの場合、グローバル・トランザクション内のダイナセットの指定行でUPDATEまたはDELETEメソッドに失敗した場合(BeginTransメソッドを発行した場合など)は、これらの指定行がロックされたままになることに注意してください。このロックは、CommitTransまたはRollbackメソッドをコールするまで解除されません。

複数のデータベースに接続してトランザクション・メソッドを使用する場合、Oracle Objects for OLEでは各データベースが個別にコミットされることに注意してください。これは、Oracle Databaseが提供する2フェーズ・コミットとは異なります。データベース間のデータ整合をアプリケーションで保証する必要がある場合は、1つのデータベースに接続した状態で、Oracle Databaseのリンク機能を使用して他のデータベースにアクセスしてください。この方法によって、Oracle Databaseの2フェーズ・コミットの利点を利用できます。2フェーズ・コミット、データベース・リンクおよび分散トランザクションの詳細は、Oracle Databaseのドキュメントを参照してください。

トランザクションは、SQL言語のデータ操作言語(DML)部分(INSERTUPDATEおよびDELETE文など)にのみ適用されます。トランザクションは、SQL言語のデータ制御言語(DCL)部分やデータ定義言語(DDL)部分(CREATEDROPALTER文など)には適用されません。DCLおよびDDLコマンドは常にコミットを強制し、前に処理したすべてを順にコミットします。

Microsoft Transaction Serverのサポート

Oracle Objects for OLE(OO4O)で開始したOracleデータベース・トランザクションは、次のすべての条件が満たされた場合、Microsoft Transaction Server(MTS)のMicrosoft Distributed Transaction Coordinator(DTC)によって調整されたグローバル・トランザクションに自動的に関与します。

  • OraSessionOpenDatabaseメソッドがORADB_ENLIST_IN_MTSオプションを使用していること

  • OO4OがMTSのグローバル・トランザクションのコンテキスト内で実行されていることが確認されていること

  • Oracle Services for Microsoft Transaction Serverがインストールされ、実行中であること


関連項目:


非同期処理

OO4Oオートメーションでは、非同期処理を使用してコマンドを実行できます。これによって、SQL文とPL/SQLブロックを非ブロック・モードで実行できます。非ブロック・モードは、CreateSQLメソッドのオプションです。


関連項目:

CreateSQLメソッド

非ブロック・モード

非ブロック・モードでは、実行が完了していない場合でも、制御がアプリケーションにただちに戻されます。このため、アプリケーションでは最後の実行結果に依存しない他のタスクを実行できます。

非ブロック・モードを有効にするには、OraSQLStmtオブジェクトの作成時に、CreateSQLメソッドにORASQL_NONBLKオプションを渡します。このモードを指定しないと、OraSQLStmtオブジェクトはブロック・モードで実行されます(デフォルト動作)。

'Create the statement in NON-BLOCKING mode 
OraSQL = Oradb.CreateSQL("delete from emp",ORASQL_NONBLK) 

非ブロック・モードで作成されたOraSQLStmtオブジェクトは、そのオブジェクトが有効な間、非ブロック・モードで実行されます。

この項の内容は次のとおりです。

非ブロック操作の状態のチェック

非同期で実行されているOraSQLStmtオブジェクトの状態を判断するには、アプリケーションでNonBlockingStateプロパティのポーリングを行う必要があります。実行が保留されている場合、NonBlockingStateプロパティはORASQL_STILL_EXECUTINGを戻し、実行が正常に完了した場合はORASQL_SUCCESSを戻します。

エラーは、例外として発生します。

正常に完了したときに、出力パラメータがあれば、その内容がバインド・パラメータ・バッファに配置されます。アプリケーションは、ブロックの場合と同様にパラメータにアクセスできます。

次の例では、NonBlockingStateプロパティの使用方法を示します。

Dim OraDatabase as OraDatabase 
Dim OraStmt as OraSQLStmt 
Dim stat as long 
Dim OraSess as OraSession 
Set OraSess = CreateObject("OracleInProcServer.XOraSession") 
Set OraDatabase =OraSess.OpenDatabase("ExampleDb", "scott/tiger", 0) 
 
'execute the select statement with NONBLOCKING mode on 
set OraStmt = OraDatabase.CreateSQL ("update emp set sal = sal + 1000", _
            ORASQL_NONBLK)
 
'Check if the call has completed 
stat = OraStmt.NonBlockingState 
while stat = ORASQL_STILL_EXECUTING 
MsgBox "Asynchronous Operation under progress" 
stat = OraStmt.NonBlockingState 
wend 
MsgBox "Asynchronous Operation completed successfully" 

非ブロック操作の取消し

実行中の非ブロック操作は、非同期コールを実行しているOraSQLStmtオブジェクトに対してCancelメソッドをコールすることによって取り消すことができます。

Dim OraDatabase as OraDatabase 
Dim OraStmt as OraSQLStmt 
Dim stat as long 
Dim OraSess as OraSession 
Set OraSess = CreateObject("OracleInProcServer.XOraSession") 
Set OraDatabase =OraSess.OpenDatabase("ExampleDb", "scott/tiger", 0) 
 
'execute the select statement with NONBLOCKING mode on 
set OraStmt = OraDatabase.CreateSQL ("update emp set sal = sal + 1000", _ 
         ORASQL_NONBLK)
 
'Check if the call has completed 
stat = OraStmt.NonBlockingState 
if stat = ORASQL_STILL_EXECUTING 
MsgBox "Cancelling the asynchronous operation that is underway" 
OraStmt.Cancel 
End if 

関連項目:

Cancelメソッド

非同期モードでの複数問合せの実行

非同期モードでは、複数の問合せを実行できます。この例では、最初の接続が非ブロック・コールを実行している間に、2番目の接続がSQL文をブロック・モードで実行します。

Dim OraSess as OraSession 
Dim OraServ as OraServer 
Dim OraDb1 as OraDatabase 
Dim OraDb2 as OraDatabase 
Dim OraStmtnonblk as OraSQLStmt 
Dim OraStmtblk as OraSQLStmt 
Dim stat as long 
set OraSess = CreateObject("OracleInProcServer.XOraSession") 
set OraDb1 = OraSess.OpenDatabase("exampledb","scott/tiger",0&) 
Set OraServ = CreateObject("OracleInProcServer.XOraServer") 
set OraDb2 = OraServ.OpenDatabase("Exampledb","scott/tiger",0&) 
 
'execute the select statement with NONBLOCKING mode on 
set OraStmtnonblk = OraDb1.CreateSQL ("update emp set sal = sal + 1000", _
             ORASQL_NONBLK) 
 
'Check if the call has completed 
stat = OraStmt.NonBlockingState 
while stat = ORASQL_STILL_EXECUTING 
  MsgBox "Asynchronous Operation under progress" 
  stat = OraStmt.NonBlockingState 
wend 
  MsgBox "Asynchronous Operation completed successfully" 
 
'execute on the second connection in BLOCKING mode 
set OraStmtblk = OraDb2.CreateSQL ("update emp set sal = sal + 500",0&) 

非ブロック化に関する制約

非ブロック・モードには次のような制約があります。

  • OraSQLStmtオブジェクトで非ブロック操作を実行している場合、そのオブジェクトのプロパティまたは属性は変更できません。これは、進行中の実行に影響を与える可能性があるためです。

  • すでにインスタンス化されている他のオブジェクトが接続上に存在する場合は、非ブロック・モードでOraSQLStmtオブジェクトを作成することはできません。つまり、非ブロック・モードでOraSQLStmtオブジェクトを作成して実行できるのは、OraDynasetOraAQなどの他のオブジェクトが、同じデータベース・セッションで現在アクティブでない場合のみです。OraParameterOraObjectオブジェクトは例外です。これらのオブジェクトは非ブロック化の実行に必要な場合があるため、許可されています。