ヘッダーをスキップ
Oracle Objects for OLE 開発者ガイド
10g リリース2(10.2)
B25023-01
  目次へ
目次
索引へ
索引

前へ
前へ
次へ
次へ
 

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への接続が可能になります。

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は、OO4O用のバージョンに依存しないプログラムIDで、Oracleクライアント・インストール・プログラムによってWindowsのレジストリに登録されます。 この名前は、グローバルな固有の識別子(CLSID)を記号化した名前で、OO4Oコンポーネントを識別します。

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_INPUTは、この初期値が入力パラメータとして使用されることを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つの単位として実行できます。 次の内容が含まれています。

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のツール製品との違いに注意してください。

複数のデータベースに接続してトランザクション・メソッドを使用する場合、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)によって調整されたグローバル・トランザクションに自動的に関与します。


関連項目:


非同期処理

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オブジェクトは例外です。 これらのオブジェクトは非ブロック化の実行に必要な場合があるため、許可されています。