Introduction to 4D for OCI

 

By Yvan Ayaay, Technical Support Engineer, 4D Inc.

TN 05-39

 

Introduction

4D for OCIプラグインによって4DOracleサーバと通信することができるようになります。このプラグインは、Oracleサーバへのネイティブアクセスを可能にするOracleAPI (Application Program Interface)であるOracle Call Interface (OCI)を使用しています。利用すれば、4th Dimensionまたは4D ServerによるどんなアプリケーションでもOracleクライアントとして動作させることができ、Oracleデータベースのデータにアクセスできるようになります。このTechnical Noteでは、4D for OCIの基本的な仕組みや簡単な操作方法について解説しています。

 

Overview

Oracle Call Interface (OCI)は、ひとつ以上のOracle Serverに対してアプリケーションから働きかけるために使用される一種のapplication programming interface (API)です。OCIでは、標準的なデータベースアクセスやデータ取得のための機能がダイナミックルーチンライブラリの形式で提供されています。4D for OCIプラグインが動作するためには、まずこのライブラリをインストールする必要があります。ライブラリを使用すればOracleデータベースに対するネイティブコネクティビティが実現し、Oracleデータベースで様々なデータベースオペレーションが実行できるようになります。OCIライブラリは、コンテキスト情報、接続情報、バインド情報、データ情報、エラー情報をストアするためのハンドルを使用します。OCIアプリケーションは、それらのハンドルによって収められている特定の情報にアクセスします。OCIではSQLを実行したり、クエリの結果を処理したりストアすることができます。

 

Installation and Configuration

4D for OCIは、Oracle 8.16Oracle 9Oracle 10データベースをサポートしています。利用には、OCIを実行するためのライブラリファイルが必要です。Oracle Technology Network WebからOracle Database Client Softwareをダウンロードすることによってファイルをインストールすることができます。http://www.oracle.com/technology/software/からインストールしたい製品のページを選択して下さい。例えば、使用OS用のOracle Database 10gが必要であれば、そのダウンロードリンクを選んで下さい。

 

OCI Library Installation for Windows

WindowsOracle Clientをインストールするのであれば、Oracle Universal Installerを使用すると便利です。ファイルをダウンロードして展開した後、Setup.exeファイルをクリックしてOracle Universal Installerを実行すれば、あとは画面の指示に従ってインストールを進めることができます。本文ではAdministratorタイプをインストールタイプとして選択しています。以下はインストールガイドのリンクです。

 

http://download-east.oracle.com/docs/cd/B19306_01/install.102/b14312/install.htm#BABJGGJH

 

OCIライブラリは、Oracle Clientと一緒にインストールされます。インストールに続いて、tnsnames.oraファイルを設定してOracleデータベースに対する接続を正しく設定して下さい。このファイルは、Oracle Clientと一緒にインストールされるNet Configuration Assistantプログラムを使用して設定することができます。Oracleデータベースの名前、プロトコル、データベースサーバのIPアドレスを入力すると、次の場所にtnsnames.oraファイルが作られます。

 

ORACLE_BASE\ORACLE_HOME\network\admin\tnsnames.ora

 

ファイルをテキストエディタなどで作成して、上記の場所に配置することもできます。それぞれのエントリーは次のフォーマットに倣っている必要があります。

 

# tnsnames.ora Network Configuration File:

C:\oracle\product\10.2.0\client_1\network\admin\tnsnames.ora

# Generated by Oracle configuration tools.

ORACLE4D =

   (DESCRIPTION =

     (ADDRESS_LIST =

       (ADDRESS = (PROTOCOL = TCP)(HOST = 10.64.0.20)(PORT = 1521))

     )

     (CONNECT_DATA =

       (SERVICE_NAME = oracle4d)

     )

   )

 

クライアントがインストールされると4D for OCIが使用できるようになります。

 

OCI Library Installation for Mac OS 10.3.x

Mac OS 10.3.9OCI LIbraryをインストールする場合、Oracle 10g Instant Client for Mac OS Xを使用することができます。Instant Clientは次の場所からダウンロードして下さい。

 

http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/ma csoft.html

 

ファイル名はinstantclient-basic-macosx-10.1.0.3.zipです。

 

以下はMac OS Xにおけるインストール手順の一例です。

NOTE:ターミナルコマンドは大文字と小文字を区別するので注意して下さい。

 

1)Oracle 10g Instant Clientを正しい場所にインストールします。フォルダ名は/Oracle、ファイルのオーナーはrootである必要があります。

instantclient-basic-macosx-10.1.0.3.zipをデスクトップに展開するとinstantclient10_1フォルダが作成されます。

ターミナルウィンドウを開きます。

sudo shコマンドを実行します。

パスワードを要求されたら入力します。sudoアクセスがないとインストールは完了できません。

mkdir /Oracleコマンドを実行します。

cp とタイプし、デスクトップからinstantclient10_1をターミナルにドラッグします。

バックスペースを押して/* /Oracleとタイプします。この時点でコマンドラインは次のようになっているはずです。

sh-2.05b# cp <your user home>/Desktop/instantclient10_1/* /Oracle

リターンキーを押します。すべてのInstant Clientファイルが/Oracleフォルダにコピーされます。

 

2)必要なOracleライブラリを正しい場所にコピーします。

cp /Oracle/libclntsh.dylib.10.1 /usr/lib/libclntsh.dylibコマンドを実行します。

chmod 777 /usr/lib/libcIntsh.dylibコマンドを実行します。

exitコマンドを実行します。これによってroot権限ではなくなります。

 

3) 4D for OCIを使用するユーザのためにenvironment.plistを作成/更新します。

cd ~コマンドを実行します。これによってホームディレクトリに移動します。

mkdir .MacOSXコマンドを実行します。ピリオドを省かないで下さい。

 

environment.plistファイルは、XMLテキストであるMacintoshプロパティファイルです。Mac OS Xのプロパティリストエディタを使用して編集することができ、テキストエディタ、あるいはターミナルのviを使用しても作成することができます。いずれにしても、内容は次のようになるはずです。

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"

"http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>

 <key>DYLD_LIBRARY_PATH</key>

 <string>/Oracle</string>

 <key>ORACLE_HOME</key>

 <string>/Oracle/OCI/oci</string>

 <key>ORA_NLS33</key>

 <string>/Oracle/OCI/oci/ocommon/nls/admin/data</string>

 <key>TNS_ADMIN</key>

 <string>/Oracle/OCI/oci/network/admin</string>

</dict>

</plist>

 

.MacOSXフォルダ以外に作成した場合は、移動して下さい。Finderはピリオドで始まるファイル名を表示しないので、ターミナルを使用します。ターミナルでファイルをコピーするには次のようにします。

 

cp <folder that contains>/environment.plist ~/.MacOSX

 

一旦、ログアウトして再びログインします。

 

NOTE:

Instant Clientファイルを/Oracleにインストールしない場合、4D for OCIのコマンドであるOCISetEnvを使用してORACLE_HOMEORA_NLS33TNS_ADMINの値を設定する必要があります。4D for OCIのデフォルト設定値は次のとおりです。

 

ORACLE_HOME=/Oracle/OCI/oci

ORA_NLS33=/Oracle/OCI/oci/ocommon/nls/admin/data TNS_ADMIN=/Oracle/OCI/oci/network/admin

 

Windowsの場合と同じように、TNSNAMES.ORAファイルを作成してOracleマシンのIPアドレスを設定する必要があります。

 

1.テキストエディタでTNSNAMES.ORAファイルを作成して次のエントリーを入力します。

 

oracle4d =

   (DESCRIPTION =

     (ADDRESS_LIST =

       (ADDRESS = (PROTOCOL =TCP)(HOST = 10.96.0.61)(POST = 1521))

    )     (CONNECT_DATA =

       (SERVICE_NAME = oracle4d)

     )

   )

 

HOSTパラメータにはOracleサーバの正しいIPアドレスを入力して下さい。

 

2.ターミナルウィンドウを開いてファイルを/private/etcディレクトリにコピーします。

クライアントがインストールされると4D for OCIが使用できるようになります。

 

NOTE:デザインモードのエクスプローラで4D for OCIが「使用しない」になっている場合、OCIライブラリが正しくインストールされていない可能性があります。

 

Basic OCI Program Structure

OCIアプリケーションは次のようなプログラムストラクチャになっています。OCIアプリケーションを開発する場合もこの流れに倣うようにして下さい。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


以下は4DOCIアプリケーションを開発する際におけるそれぞれのステップです。

 

Step1:OCIプログラミンク環境およびスレッドの作成と初期化

OCIアプリケーションの冒頭でOCI環境を作成する必要があります。すべてのOCI機能は、このコンテキストで実行されます。他のOCIコールをする前に4D for OCIコマンドのOCIEnvCreate()を呼び出さなくてはなりません。これにより、OCI環境とそのハンドルが初期化されます。他のハンドルタイプは、このハンドルを使用して割り当てられます。以下はコマンドの使用例です。

 

$error_l:=OCIEnvCreate ($Envhp;OCI_HTYPE_ENV )

 

Step2:ハンドルおよび記述子の割り当て

大抵のOCIコールはハンドルをパラメータとして使用します。ハンドルは、基本的にいってOCIライブラリによって割り当てられたソトレージエリアへのポインタです。コンテキスト、接続、データ、OCIファンクションコールに関する情報は、ハンドルで知ることができます。割り当てる必要があるハンドルには、サービスコンテキストハンドル、サーバハンドル、セッションハンドル、ステートメントハンドル、エラーハンドルがあります。

 

サービスコンテキストハンドルは、サーバに対するOCIコールの操作コンテキスト属性を定義するもので、サーバ、セッション、トランザクションハンドルで構成されています。サーバハンドルは、データベースサーバとの接続を特定します。セッションハンドルは、ユーザの立場と権限、操作コンテキストを特定します。トランザクションハンドルは、SQLが実行されるトランザクションを定義します。ステートメントハンドルは、SQLステートメントとその属性を定義します。OCIコールのパラメータとして渡されるエラーハンドルには、OCIで起きたエラーに関する情報が返されます。この情報はOCIErrorGet()コマンドで知ることができます。。以下はそれぞれのハンドルの割り当ての例です。

 

$error_l:=OCIHandleAlloc ($Envhp;$svchp;OCI_HTYPE_SVCCTX ) `Service context handle

$error_l:=OCIHandleAlloc ($Envhp;$authp;OCI_HTYPE_SESSION ) ` Session handle

$error_l:=OCIHandleAlloc ($Envhp;$srvhp;OCI_HTYPE_SERVER ) ` Server handle

$error_l:=OCIHandleAlloc ($Envhp;$Stmthp;OCI_HTYPE_STMT ) `Statement  Handle

$error_l:=OCIHandleAlloc ($Envhp;$errhp;OCI_HTYPE_ERROR ) ` Error handle

 

Step3:サーバ接続およびユーザセッションの確立

OCI環境が初期化されてハンドルが割り当てられたならば、次のステップはサーバ接続を確立してユーザセッションを開始することです。これにはふたつのオプションが用意されています。シングルユーザ/セッション、またはマルチプルユーザ/セッションです。

 

それぞれのデータベース接続に対して単一のユーザセッションだけが必要なのであれば、簡略化されたログインコールOCILogon()を使用することができます。次のコードに示されているように環境、エラー、サービスコンテキストハンドルがデータベースアクセスパラメータと一緒に渡されます。

 

$error_l:=OCILogon ($Envhp;$errhp;$svchp;"scott";"tiger";"oracle4d")

 

マルチプルユーザセッションの場合、個別のOCIコールが使用されます。次のコードに示されているように、サーバに対するアクセスパスがOCIServerAttach()で作成され、次いでサーバ属性が設定されます。ユーザセッションはOCISessionBegin,によって確立されます。

 

$error_l:=OCIServerAttach ($srvhp;$errhp;"oracle4d")

$error_l:=OCIAttrSetVal ($svchp;$srvhp;OCI_ATTR_SERVER ;$errhp)

$error_l:=OCIAttrSetText  ($authp;"scott";22;$errhp)

$error_l:=OCIAttrSetText ($authp;"tiger";23;$errhp)

$error_l:=OCISessionBegin ($svchp;$errhp;$authp;1;0)

$error_l:=OCIAttrSetVal ($svchp;$authp;OCI_ATTR_SESSION ;$errhp)

 

Step 4:SQLの発行およびデータの処理

サーバとの接続が確立し、ユーザセッションが開始したならば、SQLステートメントを実行することによってデータベースサーバのデータにアクセスすることができるようになります。Oracleデータベースのテーブルに入っているデータを更新したり、データを取り出して配列、変数、フィールドなどに入れたりすることができます。DML (Data Manipulation Language)、たとえばINSERTUPDATEDELETEなどのコマンドを使用してデータを更新する場合、ステートメントの前に入力変数のバインドを実行する必要があります。逆にSQLステートメントを使用してデータを取り出す場合、出力変数の定義が必要です。どちらの場合においても、SQLステートメントの準備をしなくてはなりません。バインドや定義の前にはOCIStmtPrepare()を次のように実行します。

 

$error_l:=OCIStmtPrepare ($Stmthp;$Errhp;$sql_t;OCI_DEFAULT )

 

Binding: Changing data in the database.

SQLステートメントの一部としてOracleにデータを渡す場合、ステートメントのプレースホルダーと対応する4Dの入力変数をバインドする必要があります。たとえばINSERTを実行する前にはデータを4Dの変数に代入し、バインドを通してOracleに渡します。DMLステートメントやクエリを入力変数で実行する場合、OCIBindByPos()OCIBindByName()を使用してそれぞれの入力変数や配列をステートメントの中にあるプレースホルダーにバインドします。

 

たとえばINSERT INTO DEPT (DEPTNO,DNAME, LOC) VALUES (:DEPTNO,:DName,:LOC)というステートメントを使用する場合、4Dの変数であるdeptnodnamelocationを次のようなコードでバインドすることができます。

 

myptrvar1:=Get pointer("deptno")

myptrvar2:=Get pointer("dname")

myptrvar3:=Get pointer("location")

$error_l:=OCIBindByPos ($Stmthp;$dpp;$Errhp;1;myptrvar1;SQLT_INT ;tindp;trlenp;trcodep;OCI_DEFAULT )

$error_l:=OCIBindByPos ($Stmthp;$dpp;$Errhp;2;myptrvar2;SQLT_STR ;tindp;trlenp;trcodep;OCI_DEFAULT )

$error_l:=OCIBindByPos ($Stmthp;$dpp;$Errhp;3;myptrvar3;SQLT_STR ;tindp;trlenp;trcodep;OCI_DEFAULT )

 

バインドに続いてOCIStmtExecute()コマンドでステートメントを実行します。

 

Defining: Retrieving data from an Oracle database.

クエリを実行するとOracleから4Dにデータが返されるので、出力変数を4D側で定義する必要があります。出力変数を定義すると返された結果のストアされる場所とデータフォーマットタイプが関連づけられます。たとえばSelect job from EmployeeのようなSQLを実行する場合、出力変数としての配列を次のようなコードで定義することができます。

 

` SQL Statement: Select job from Employee

ARRAY TEXT(Returnvalue_at;0)

$error_l:=OCIDefineByPos ($Stmthp;$define;$Errhp;1;->vReturnvalue_at;SQLT_STR ;tindp;trlenp;trcodep;OCI_DEFAULT

 

ステートメントが実行された後には、結果をテキスト変数Returnvalue_atから取る必要があります。OCIDefineByPosコマンドの4番目のパラメータは出力変数の割り当てられたSQLステートメントにおける列の番号です。結果を取るにはOCIStmtFetch()コマンドを使用します。

 

$error_l:=OCIStmtPrepare ($Stmthp;$Errhp;$sql_t;OCI_DEFAULT )  `Length($sql_t))

  ` *** Prepare SQL statement

If ($error_l=0)

  $error_l:=OCIDefineByPos ($Stmthp;$define;$Errhp;1;>vReturnvalue_t;SQLT_STR ;tindp;trlenp;trcodep;OCI_DEFAULT )

    ` *** Bind Oracle variable by position toward 4D

  If ($error_l=0)

   $error_l:=OCIStmtExecute ($svchp;$Stmthp;$Errhp;0;0;0;0;OCI_DEFAULT )

     ` *** Execute the SQL statment

   If If($error_l=0)

   Repeat

     $error_l:=OCIStmtFetch ($Stmthp;$Errhp;1)  ` *** Fetch the result 1 row at the time

     If ($error_l=0)

      APPEND TO ARRAY(Returnvalue_at;vReturnvalue_t)

     End if

   Until ($error_l=OCI_NO_DATA )

  End if

End if

 

Step5:コミット

変更をデータベースに反映させるにはOCITransCommit()コマンドでコミットを実行することが必要です。パラメータには、次のようにサービスコンテキストハンドルを渡します。コミットをすることなくデータベースが終了した場合、自動的なロールバックの結果として変更が無効になります。

 

$error_l:=OCITransCommit  ($svchp;$Errhp;OCI_DEFAULT )

 

Step6:ユーザセッションおよびサーバ接続の終了

アプリケーションを終了する前にはユーザセッションとサーバへの接続を終了する必要があります。それぞれの終了に使用するコマンドはOCISessionEnd()OCIServerDetach()です。

 

Step7:ハンドルの解放

OCIアプリケーションで不要になったハンドルは、すべてOCIHandleFree()コマンドで解放する必要があります。

 

OCI Basic Operations

ここからはOCIでサポートされる基本的な操作を幾つか考慮します。最初の例題ではOracleデータベースからデータを取り出して結果を配列に収めます。2番目の例題ではOracleデータベースにデータを挿入します。

 

Example1:SQLを使用してOracleデータベースからデータを取り出す

 

Example2:Oracleデータベースにデータを挿入する

 

Summary

4D for OCIプラグインは、OCI (Oracle Call Interface) APIによるOracleデータベースへのアクセスを可能にします。はじめにOCIライブラリをインストールする必要があり、サーバ用にtnsnames.oraファイルを設定しなくてはなりません。Oracleデータベースに対するネイティブアクセスは、OCIライブラリが実行します。4DによるOCIアプリケーションは、OCIのプログラムフローに従います。OCIのプログラムフローは、環境の作成、ハンドルの割り当て、サーバへの接続、セッションの開始、SQLステートメントの処理、接続解除、ハンドルの解放という順序になります。4D for OCIプラグインを使用すれば4DOracleデータベースに通信することができます。

 

Example1:

 

  `Method: QueryData

  `Description: This method will retrieved data from Oracle database and place the result

  ` into an array.

C_LONGINT($error_l)

C_LONGINT($Envhp;$errhp;$svchp;$authp;$srvhp)

C_LONGINT($srvhp;$svchp;$authp;$errhp)

ARRAY TEXT(Returnvalue_at;0)

C_TEXT(vReturnvalue_t;null_t)

C_POINTER(tindp;trlenp;trcodep)

tindp:=->null_t  ` *** Provide a null value to the text variable

C_TEXT($sql_t)

  ` Select statement.

$sql_t:="Select job from emp"

  ` *** Create the OCI Environment

$error_l:=OCIEnvCreate ($Envhp;OCI_HTYPE_ENV )

If ($error_l=0)

  `*** Allocate Handles and Data Structures

$error_l:=OCIHandleAlloc ($Envhp;$errhp;OCI_HTYPE_ERROR )  ` Allocate Error handle.

If ($error_l=0)

  $error_l:=OCIHandleAlloc ($Envhp;$svchp;OCI_HTYPE_SVCCTX )  `Allocate Service

  Context Handle.

  If ($error_l=0)

   $error_l:=OCIHandleAlloc ($Envhp;$authp;OCI_HTYPE_SESSION )

     ` Allocate User Session Handle

   If ($error_l=0)

    $error_l:=OCIHandleAlloc ($Envhp;$srvhp;OCI_HTYPE_SERVER )

      `Allocate Server session handle

    If ($error_l=0)

     $loginok_b:=True

    End if

   End if

  End if

End if

End if

  ` *** Connect to Server

$define:=0

If ($error_l=0)

$error_l:=OCILogon ($Envhp;$errhp;$svchp;"scott";"tiger";"oracle4d")  ` connect server

using simple logon call.

  `**** Issue SQL Statement

If ($error_l=0)

  $error_l:=OCIHandleAlloc ($Envhp;$Stmthp;OCI_HTYPE_STMT )  ` *** Create SQL

  Statement Handler

  If ($error_l=0)

   $error_l:=OCIStmtPrepare ($Stmthp;$Errhp;$sql_t;Length($sql_t))  ` *** Prepare SQL

   statement

   If ($error_l=0)

    $error_l:=OCIDefineByPos ($Stmthp;$define;$Errhp;1;->vReturnvalue_t;SQLT_STR

    ;tindp;trlenp;trcodep;OCI_DEFAULT )  ` *** Define output variables

    If ($error_l=0)

     $error_l:=OCIStmtExecute ($svchp;$Stmthp;$Errhp;0;0;0;0;OCI_DEFAULT )  ` * * *

     Execute the SQL statment

     If ($error_l=0)

      Repeat

       $error_l:=OCIStmtFetch ($Stmthp;$Errhp;1)  ` *** Fetch the result 1 row at

       the time

       If ($error_l=0)

        APPEND TO ARRAY(Returnvalue_at;vReturnvalue_t)  ` *** Put fetch results

        into array.

       End if

      Until ($error_l=OCI_NO_DATA )

     End if

    End if

    $error_l:=OCIHandleFree ($Stmthp)

   End if

  End if

End if

End if

If ($loginok_b)

  ` * * *Disconnect from server

$error_I:=OCILogoff ($svchp;$errhp)

  `***** Free Handles

$error_l:=OCIHandleFree ($svchp)

$error_l:=OCIHandleFree ($srvhp)

$error_l:=OCIHandleFree ($errhp)

$error_l:=OCIHandleFree ($authp)

End if

 

Example2:

 

 `Method: InsertData

  `Description: This method will insert a record in the Oracle database.

C_LONGINT($error_l)

C_LONGINT($Envhp;$errhp;$svchp;$authp;$srvhp)

C_LONGINT($srvhp;$svchp;$authp;$errhp)

C_TEXT(vReturnvalue_t;null_t)

C_POINTER(tindp;trlenp;trcodep)

C_POINTER(myptrvar1;myptrvar2;myptrvar3)

C_LONGINT(deptno1)

C_TEXT(dname1;loc1)

C_TEXT($sql_t)

deptno1:=12

dname1:="Management"

loc1:="Seattle"

myptrvar1:=Get pointer("deptno1")

myptrvar2:=Get pointer("dname1")

myptrvar3:=Get pointer("loc1")

tindp:=->null_t  ` *** Provide a null value to the text variable

  ` SQL STATEMENT to insert record to DEPT table in Oracle.

  `The variables preceded by : are place holders.

$sql_t:="INSERT INTO DEPT (DEPTNO,DNAME, LOC) VALUES (:DEPTNO,:DName,:LOC)"

  ` *** Create the OCI Environment

$error_l:=OCIEnvCreate ($Envhp;OCI_HTYPE_ENV )

If ($error_l=0)

    `*** Allocate Handles and Data Structures

  $error_l:=OCIHandleAlloc ($Envhp;$errhp;OCI_HTYPE_ERROR )

    ` Allocate Error handle.

  If ($error_l=0)

   $error_l:=OCIHandleAlloc ($Envhp;$svchp;OCI_HTYPE_SVCCTX )

     `Allocate Service Context Handle.

   If ($error_l=0)

     $error_l:=OCIHandleAlloc ($Envhp;$authp;OCI_HTYPE_SESSION )

       ` Allocate User Session Handle

     If ($error_l=0)

      $error_l:=OCIHandleAlloc ($Envhp;$srvhp;OCI_HTYPE_SERVER )

        `Allocate Server session handle

      If ($error_l=0)

        $loginok_b:=True

      End if

     End if

   End if

  End if

End if

  ` *** Connect to Server and Begin Session

$define:=0

If ($error_l=0)

  $error_l:=OCIServerAttach ($srvhp;$errhp;"oracle4d")

    `Create access path to oracle database

  If ($error_l=0)

   $error_l:=OCIAttrSetVal ($svchp;$srvhp;OCI_ATTR_SERVER ;$errhp)

     ` Set server attributes

   If ($error_l=0)

     $error_l:=OCIAttrSetText ($authp;"scott";22;$errhp)  `Set user name to access

     server. 22 is attribute type.

     If ($error_l=0)

      $error_l:=OCIAttrSetText ($authp;"tiger";23;$errhp)  ` Set password. 23 is attribute

      type.

      If ($error_l=0)

        $error_l:=OCISessionBegin ($svchp;$errhp;$authp;1;0)  ` Begin user session

        If ($error_l=0)

         $error_l:=OCIAttrSetVal ($svchp;$authp;OCI_ATTR_SESSION ;$errhp)  `Set

         session attribute

           `**** Issue SQL Statement

         If ($error_l=0)

           $error_l:=OCIHandleAlloc ($Envhp;$Stmthp;OCI_HTYPE_STMT )

             ` *** Create SQL Statement Handler

           If ($error_l=0)

            $error_l:=OCIStmtPrepare ($Stmthp;$Errhp;$sql_t;Length($sql_t))

              ` *** Prepare SQL statement

            If ($error_l=0)

                ` ***Bind variables to positions in the SQL statement.

                `The 4th parameter is the position in the SQL Statment, the 5th parameter is

                ` a pointer to the variable to bind, and the 6th parameter is the data type.

              $error_l:=OCIBindByPos ($Stmthp;$dpp;$Errhp;1;myptrvar1;SQLT_INT

              ;tindp;trlenp;trcodep;OCI_DEFAULT )

              $error_l:=OCIBindByPos ($Stmthp;$dpp;$Errhp;2;myptrvar2;SQLT_STR

              ;tindp;trlenp;trcodep;OCI_DEFAULT )

              $error_l:=OCIBindByPos ($Stmthp;$dpp;$Errhp;3;myptrvar3;SQLT_STR

              ;tindp;trlenp;trcodep;OCI_DEFAULT )

              If ($error_l=0)

               $error_l:=OCIStmtExecute ($svchp;$Stmthp;$Errhp;1;0;0;OCI_DEFAULT )

                 ` *** Execute the SQL statment

               $error_l:=OCITransCommit ($svchp;$Errhp;OCI_DEFAULT )

                 `*** Commit changes to database.

              End if

                `*** Free statement handle.

              $error_l:=OCIHandleFree ($Stmthp)

            End if

           End if

         End if

        End if

      End if

     End if

   End if

  End if

End if

If ($loginok_b)

    ` * * *Disconnect from server

  $error_l:=OCISessionEnd ($svchp;$errhp;$authp)

  $error_l:=OCIServerDetach ($srvhp;$errhp)

   `***** Free Handles

  $error_l:=OCIHandleFree ($svchp)

  $error_l:=OCIHandleFree ($srvhp)

  $error_l:=OCIHandleFree ($errhp)

  $error_l:=OCIHandleFree ($authp)

End if