Previous | Table of Contents | Next |
External LOBs
External LOBs are stored as files outside the database and do not participate in the transactional model. External LOBs are stored as BFILE datatype, which is actually a pointer to a file.
Oracle8 supports the calling of DLL functions and procedures from PL/SQL code. As a result, you can have data cartridges whose methods are external C routines. By using external C routines, developers can take advantage of the efficiency of a 3GL, and can use the flexibility of calling Win32 APIs and manipulating COM objects.
There are two steps before a developer can call an external procedure from PL/SQL:
Create or replace library external_lib as e:/datacartridge/debug/cartridge.dll;
The following example shows how to implement an object type that uses an external procedure as a method:
Create or replace package data_package as function ext_func (data CLOB) return binary_integer; end; create or replace package body data_package as function ext_func (data CLOB) return binary_integer is external name c_func library external_lib language C with context parameters ( context, data OCILOBLOCATOR ); end; create or replace type ext_objtype as object ( data CLOB, member function ext_objtype_func return binary_integer ); Create or replace type body ext_objtype is member function ext_objtype_func return binary_integer is begin return data_package.ext_func(data); end; end;
The following C code shows the function prototype of the external function:
#Include <oci.h> #define DLLEXPORT __declspec(dllexport) __cdecl int DLLEXPORT c_func (OCIExtProcContext *ctx, OCILobLocator *lobl); int c_func (OCIExtProcContext *ctx, OCILobLocator *lobl) { /*Place function code here */ return 0; }
The following code shows the testing of the external callout using PL/SQL:
Declare i binary_integer; x ext_objtype; begin x := ext_objtype(EMPTY_CLOB()); I := x.ext_objtype_func(); DBMS_OUTPUT.PUT_LINE(ext_objtype_func() returned || I); end;
OCI Callbacks
In Release 8.0.3, Oracle introduced four new OCI APIs, which can be used for external procedure callbacks. External routines can call back the Oracle8 Server using the OCI interface:
An external procedure can perform the following functions using these OCI APIs:
Debugging External Procedures
Traditionally, a developer could use Visual C++s symbolic debugger to set break points in a DLL loaded by a process without symbolic debugging information. External procedures cannot be debugged in this manner because debugging must be spawned on demand by the listener process. Embedding the DebugBreak() Win32 API call at the beginning of an external procedure will allow developers to debug these procedures.
The following details the development of a data cartridge Data Store. This cartridge can be used to store a set of data in an Oracle8 character LOB (CLOB). The stored data can be processed for statistical analysis such as minimum and maximum values, averages, regression, and so on.
Create or replace type DataStore as object ( pid integer, name varchar2(20), date_created date, value clob, member function DataMinimum return integer, member function DataMaximum return integer, pragma restrict_references(DataMinimum, WNDS, WNPS), pragma restrict_references(DataMaximum, WNDS, WNPS));
Create or replace package DataStore_package as function datastore_findmin (data clob) return integer; function datastore_findmax (data clob) return integer; pragma restrict_references (datastore_findmin, WNDS, WNPS); pragma restrict_references (datastore_findmin, WNDS, WNPS); end;
Create or replace type body DataStore is member function DataMinimum return integer is x integer := DataStore_package.datastore_findmin(data); begin return x ; end; member function DataMaximum return integer is y integer := DataStore_package.datastore_findmax(data); begin return y ; end; end;
Create or replace library datastore_lib as <directory_of_library> / libdatastore.so
Create or replace package body DataStore_package as function datastore_findmin(data clob) return integer is external name c_minimum library datastore_lib language c with context; function datastore_findmax(data clob) return integer is external name c_maximum library datastore_lib language c with context; end;
#Include <oci.h> int c_minimum (OCIExtProcContext *ctx, OCILobLocator *lobl) { ub1 bufp[MAXBUFLEN]; sword retval; init_handles (ctx); retval = OCILobRead(...., lobl, bufp, ....); return (process_min(bufp)); } #Include <oci.h> int c_maximum (OCIExtProcContext *ctx, OCILobLocator *lobl) { ub1 bufp[MAXBUFLEN]; sword retval; init_handles (ctx); retval = OCILobRead(...., lobl, bufp, ....); return (process_max(bufp)); }
Previous | Table of Contents | Next |