
Purpose: Database Framework Low-Level Oracle Client Interface Access
- this unit is a part of the Open Source Synopse mORMot framework 2, licensed under a MPL/GPL/LGPL three license - see LICENSE.md
| Unit Name | Description | |
|---|---|---|
| mormot.core.base | Framework Core Shared Types and RTL-like Functions | |
| mormot.core.datetime | Framework Core Low-Level Date and Time Support | |
| mormot.core.log | Framework Core Logging | |
| mormot.core.os | Framework Core Low-Level Wrappers to the Operating-System API | |
| mormot.core.rtti | Framework Core Low-Level Cross-Compiler RTTI Definitions | |
| mormot.core.text | Framework Core Low-Level Text Processing | |
| mormot.core.unicode | Framework Core Low-Level Unicode UTF-8 UTF-16 Ansi Conversion | |
| mormot.db.core | Database Framework Core Types and Classes | |
| mormot.db.sql | Database Framework Shared Abstract SQL Types and Classes |
| Objects | Description | |
|---|---|---|
| ESqlDBOracle | Exception type associated to the native Oracle Client Interface (OCI) | |
| OCINumber | Oracle native number low-level representation | |
| TOracleDate | Memory structure used to store a date and time in native Oracle format | |
| TSqlDBOracleLib | Direct access to the native Oracle Client Interface (OCI) |
OCINumber = packed record
Oracle native number low-level representation
TOracleDate = object(TObject)
Memory structure used to store a date and time in native Oracle format
- follow the SQLT_DAT column type layout
function ToDateTime: TDateTime;
Convert an Oracle date and time into Delphi TDateTime
- this method will ignore any date before 30 Dec 1899 (i.e. any TDateTime result < 0), to avoid e.g. wrong DecodeTime() computation from retrieved value: if you need to retrieve dates before 1899, you should better retrieve the content using ISO-8601 text encoding
function ToIso8601(Dest: PUtf8Char): integer; overload;
Convert an Oracle date and time into its textual expanded ISO-8601
- will fill up to 21 characters, including double quotes
procedure From(const aIso8601: RawUtf8); overload;
Convert textual ISO-8601 into native Oracle date and time format
procedure From(const aValue: TDateTime); overload;
Convert Delphi TDateTime into native Oracle date and time format
procedure From(aIso8601: PUtf8Char; Length: integer); overload;
Convert textual ISO-8601 into native Oracle date and time format
procedure ToIso8601(var aIso8601: RawUtf8); overload;
Convert an Oracle date and time into its textual expanded ISO-8601
- return the ISO-8601 text, without double quotes
TSqlDBOracleLib = class(TSynLibrary)
Direct access to the native Oracle Client Interface (OCI)
major_version: sword;
The client verion numbers
minor_version: sword;
The client verion numbers
patch_num: sword;
The client verion numbers
port_update_num: sword;
The client verion numbers
SupportsInt64Params: boolean;
If OCI handles directly Int64 bound parameters (revision >= 11.2)
update_num: sword;
The client verion numbers
UseLobChunks: boolean;
OCI will call OCILobGetChunkSize when retrieving BLOB/CLOB content
- is enabled by default, to avoid ORA-2481 errors when reading more than 96 MB of data, but you may disable chunking if you prefer by setting false
constructor Create(LibraryFileName: TFileName = '');
Load the oci.dll library
- and retrieve all Oci*() addresses for OCI_ENTRIES[] items
function ClientRevision: RawUtf8;
Retrieve the client version as 'oci.dll rev. 11.2.0.1'
function ClobFromDescriptor(Stmt: TSqlDBStatement; svchp: POCISvcCtx; errhp: POCIError; locp: POCIDescriptor; ColumnDBForm: integer; out Text: RawUtf8; TextResize: boolean = true): ub4;
Retrieve some CLOB/NCLOB content as UTF-8 text
function CodePageToCharSetID(env: pointer; aCodePage: cardinal): cardinal;
Retrieve the OCI charset ID from a Windows Code Page
- will only handle most known Windows Code Page
- if aCodePage=0, will use the NLS_LANG environment variable
- will use 'WE8MSWIN1252' (CP_WINANSI) if the Code Page is unknown
procedure BlobFromDescriptor(Stmt: TSqlDBStatement; svchp: POCISvcCtx; errhp: POCIError; locp: POCIDescriptor; out result: TBytes); overload;
Retrieve some BLOB content
procedure BlobFromDescriptor(Stmt: TSqlDBStatement; svchp: POCISvcCtx; errhp: POCIError; locp: POCIDescriptor; out result: RawByteString); overload;
Retrieve some BLOB content
procedure BlobFromDescriptorToStream(Stmt: TSqlDBStatement; svchp: POCISvcCtx; errhp: POCIError; locp: POCIDescriptor; stream: TStream);
Retrieve some BLOB content, save it to the stream
procedure BlobToDescriptorFromStream(Stmt: TSqlDBStatement; svchp: POCISvcCtx; errhp: POCIError; locp: POCIDescriptor; stream: TStream);
Write some BLOB content, read it from the stream
procedure Check(Conn: TSqlDBConnection; Stmt: TSqlDBStatement; Status: integer; ErrorHandle: POCIError; InfoRaiseException: boolean = false; LogLevelNoRaise: TSynLogLevel = sllNone);
Raise an exception on error
ESqlDBOracle = class(ESqlDBException)
Exception type associated to the native Oracle Client Interface (OCI)
OCIDuration = ub2;
OCIDuration - OCI object duration
- A client can specify the duration of which an object is pinned (pin duration) and the duration of which the object is in memory (allocation duration). If the objects are still pinned at the end of the pin duration, the object cache manager will automatically unpin the objects for the client. If the objects still exist at the end of the allocation duration, the object cache manager will automatically free the objects for the client.
- Objects that are pinned with the option OCI_DURATION_TRANS will get unpinned automatically at the end of the current transaction.
- Objects that are pinned with the option OCI_DURATION_SESSION will get unpinned automatically at the end of the current session (connection).
- The option OCI_DURATION_NULL is used when the client does not want to set the pin duration. If the object is already loaded into the cache, then the pin duration will remain the same. If the object is not yet loaded, the pin duration of the object will be set to OCI_DURATION_DEFAULT.
OCITypeCode = ub2;
The OCITypeCode type is interchangeable with the existing SQLT type which is a ub2
PSqlT_VNU = ^TSQLT_VNU;
Points to a Oracle VARNUM memory structure
TOracleDateArray = array[0..(maxInt div SizeOf(TOracleDate)) - 1] of TOracleDate;
Wrapper to an array of TOracleDate items
TSqlT_VNU = array[0..21] of byte;
Oracle VARNUM memory structure
OCI_ATTR_AGENT_ADDRESS = 65;
Agent name
OCI_ATTR_AGENT_NAME = 64;
OCI_ATTR_AGENT_PROTOCOL = 66;
Agent address
OCI_ATTR_BUF_ADDR = 76;
Default date format string
OCI_ATTR_BUF_SIZE = 77;
Buffer address
OCI_ATTR_CACHE = 115;
Increment value
OCI_ATTR_CLUSTERED = 105;
DBA of the segment header
OCI_ATTR_COL_COUNT = 82;
Number of rows in column array NOTE that OCI_ATTR_NUM_COLS is a column array attribute too.
OCI_ATTR_DATEFORMAT = 75;
Row offset in the array
OCI_ATTR_DEFAULT_LOBPREFETCH_SIZE = 438;
Rows fetched in last call
OCI_ATTR_DIRPATH_MODE = 78;
Buffer size
OCI_ATTR_DIRPATH_NOLOG = 79;
Mode of direct path operation
OCI_ATTR_DIRPATH_PARALLEL = 80;
Nologging option
OCI_ATTR_DML_ROW_OFFSET = 74;
Num of errs in array DML
OCI_ATTR_DURATION = 132;
Whether table is typed
OCI_ATTR_HW_MARK = 117;
Whether the sequence is ordered
OCI_ATTR_INCR = 114;
Maximum value
OCI_ATTR_INDEX_ONLY = 107;
Whether the table is partitioned
OCI_ATTR_INITIAL_CLIENT_ROLES = 100;
Proxy user credentials
OCI_ATTR_IS_INVOKER_RIGHTS = 133;
Duration of temporary table
OCI_ATTR_IS_TEMPORARY = 130;
Parse Error offset
OCI_ATTR_IS_TYPED = 131;
Whether table is temporary
OCI_ATTR_LINK = 111;
REF to the type descriptor
OCI_ATTR_LIST_ARGUMENTS = 108;
Whether the table is index only
OCI_ATTR_LIST_COLUMNS = 103;
Number of columns
OCI_ATTR_LIST_SUBPROGRAMS = 109;
Parameter of the argument list
OCI_ATTR_LTYPE = 128;
TDO of a type
OCI_ATTR_MAX = 113;
Minimum value
OCI_ATTR_MEMPOOL_APPNAME = 90;
Instance name
OCI_ATTR_MEMPOOL_HOMENAME = 91;
Application name
OCI_ATTR_MEMPOOL_INSTNAME = 89;
Pool Size
OCI_ATTR_MEMPOOL_MODEL = 92;
Home Directory name
OCI_ATTR_MEMPOOL_SIZE = 88;
Temporary LOBs
OCI_ATTR_MIGSESSION = 86;
Server group name
OCI_ATTR_MIN = 112;
The database link name
OCI_ATTR_MODES = 93;
Pool Model (proc,thrd,both)
OCI_ATTR_MSG_PROP = 72;
Message id
OCI_ATTR_NFY_MSGID = 71;
Queue name
OCI_ATTR_NOCACHE = 87;
Migratable session attribute
OCI_ATTR_NUM_ATTRS = 120;
Timestamp of the object
OCI_ATTR_NUM_COLS = 102;
Unknown attribute
OCI_ATTR_NUM_DML_ERRORS = 73;
Message properties
OCI_ATTR_NUM_PARAMS = 121;
Number of sttributes
OCI_ATTR_NUM_ROWS = 81;
Parallel (temp seg) option
OCI_ATTR_OBJID = 122;
Number of parameters
OCI_ATTR_OBJ_ID = 136;
Schema name
OCI_ATTR_OBJ_NAME = 134;
Is invoker rights
OCI_ATTR_OBJ_SCHEMA = 135;
Top level schema obj name
OCI_ATTR_ORDER = 116;
Number of sequence numbers cached
OCI_ATTR_ORIGINAL_MSGID = 69;
Sender id
OCI_ATTR_OVERLOAD_ID = 125;
Parameter descriptor
OCI_ATTR_PARAM = 124;
Type of info described by
OCI_ATTR_PARSE_ERROR_OFFSET = 129;
List type
OCI_ATTR_PARTITIONED = 106;
Whether the table is clustered
OCI_ATTR_PROXY_CREDENTIALS = 99;
Associated namespace
OCI_ATTR_PTYPE = 123;
Object id for a table or view
OCI_ATTR_QUEUE_NAME = 70;
Original message id
OCI_ATTR_RDBA = 104;
Parameter of the column list
OCI_ATTR_REF_TDO = 110;
Parameter of the subprogram list
OCI_ATTR_ROWS_FETCHED = 197;
Size of the stm cache
OCI_ATTR_SENDER_ID = 68;
Agent protocol
OCI_ATTR_SERVER_GROUP = 85;
Shared Heap Allocation Size
OCI_ATTR_SHARED_HEAPALLOC = 84;
Str off of last row processed
OCI_ATTR_STMTCACHESIZE = 176;
Top level schema object id
OCI_ATTR_STREAM_OFFSET = 83;
Columns of column array processed so far.
OCI_ATTR_SUBSCR_CALLBACK = 95;
Name of subscription
OCI_ATTR_SUBSCR_CTX = 96;
Associated callback
OCI_ATTR_SUBSCR_NAME = 94;
Modes
OCI_ATTR_SUBSCR_NAMESPACE = 98;
Associated payload
OCI_ATTR_SUBSCR_PAYLOAD = 97;
Associated callback context
OCI_ATTR_TABLESPACE = 126;
Overload ID for funcs and procs
OCI_ATTR_TDO = 127;
Table name space
OCI_ATTR_TIMESTAMP = 119;
Type's schema name
OCI_ATTR_TYPE_SCHEMA = 118;
High-water mark
OCI_ATTR_UNK = 101;
Initial client role list
OCI_DURATION_CALL: OCIDuration = OCI_DURATION_BEGIN_ + 2;
WILL BE REMOVED/CHANGED IN A FUTURE RELEASE
OCI_DURATION_CALLOUT: OCIDuration = OCI_DURATION_CALLOUT_;
This is to be used only during callouts. It is similar to that of OCI_DURATION_CALL, but lasts only for the duration of a callout. Its heap is from PGA
OCI_DURATION_PROCESS: OCIDuration = OCI_DURATION_BEGIN_ - 5;
Last of predefined durations This is not being treated as other predefined durations such as SESSION, CALL etc, because this would not have an entry in the duration table and its functionality is primitive such that only allocate, free, resize memory are allowed, but one cannot create subduration out of this
OCI_DURATION_STATEMENT: OCIDuration = OCI_DURATION_BEGIN_ + 3;
The end of user client/server call
OCI_OBJECTFREE_FORCE : ub2 = $0001;
OCIObjectFreeFlag - Object free flag
- If OCI_OBJECTCOPY_FORCE is specified when freeing an instance, the instance is freed regardless it is pinned or diritied. If OCI_OBJECTCOPY_NONULL is specified when freeing an instance, the null structure is not freed.
OCI_TYPECODE_BDOUBLE = SQLT_IBDOUBLE;
Binary float
OCI_TYPECODE_BFILE = SQLT_BFILEE;
SQL/OTS BINARY LARGE OBJECT
OCI_TYPECODE_BFLOAT = SQLT_IBFLOAT;
SQL DOUBLE PRECISION OTS SQL_DOUBLE
OCI_TYPECODE_BLOB = SQLT_BLOB;
SQL/OTS NAMED COLLECTION TYPE
OCI_TYPECODE_CFILE = SQLT_CFILEE;
SQL/OTS CHARACTER LARGE OBJECT
OCI_TYPECODE_CHAR = SQLT_AFC;
SQL VARCHAR2(N) OTS SQL_VARCHAR2(N)
OCI_TYPECODE_CLOB = SQLT_CLOB;
SQL/OTS BINARY FILE OBJECT
OCI_TYPECODE_DATE = SQLT_DAT;
SQL/OTS OBJECT REFERENCE
OCI_TYPECODE_DECIMAL = SQLT_PDN;
SQL NUMBER(P S) OTS NUMBER(P S)
OCI_TYPECODE_DOUBLE = 22;
SQL REAL OTS SQL_REAL
OCI_TYPECODE_ERRHP = 283;
To indicate error has to be taken from error handle - reserved for sqlplus use
OCI_TYPECODE_FLOAT = SQLT_FLT;
Binary double
OCI_TYPECODE_INTEGER = SQLT_INT;
SQL SMALLINT OTS SMALLINT
OCI_TYPECODE_INTERVAL_DS = SQLT_INTERVAL_DS;
SQL/OTS INTRVL YR-MON
OCI_TYPECODE_INTERVAL_YM = SQLT_INTERVAL_YM;
TIMESTAMP_LTZ
OCI_TYPECODE_MLSLABEL = SQLT_LAB;
SQL VARCHAR(N) OTS SQL_VARCHAR(N)
OCI_TYPECODE_NAMEDCOLLECTION = SQLT_NCO;
SQL/OTS Opaque Types
OCI_TYPECODE_NCHAR = 286;
Type code for PLS_INTEGER / the following are PL/SQL-only internal. They should not be used OCI_TYPECODE_ITABLE = SQLT_TAB; // PLSQL indexed table OCI_TYPECODE_RECORD = SQLT_REC; // PLSQL record OCI_TYPECODE_boolean = SQLT_BOL; // PLSQL boolean NOTE : The following NCHAR related codes are just short forms for saying OCI_TYPECODE_VARCHAR2 with a charset form of SQLCS_NCHAR. These codes are intended for use in the OCIAnyData API only and nowhere else.
OCI_TYPECODE_NONE = 0;
To indicate absence of typecode being specified
OCI_TYPECODE_NUMBER = SQLT_NUM;
SQL FLOAT(P) OTS FLOAT(P)
OCI_TYPECODE_OBJECT = SQLT_NTY;
SQL TABLE OTS MULTISET
OCI_TYPECODE_OCTET = 245;
SQL UNSIGNED INTEGER(32) OTS UINT32
OCI_TYPECODE_OPAQUE = 58;
SQL/OTS NAMED OBJECT TYPE
OCI_TYPECODE_OTMFIRST = 228;
Urowid type
OCI_TYPECODE_OTMLAST = 320;
First Open Type Manager typecode
OCI_TYPECODE_PLS_INTEGER = 266;
Last OTM system type (internal)
OCI_TYPECODE_PTR = 32;
SQL RAW(N) OTS RAW(N)
OCI_TYPECODE_RAW = SQLT_LVB;
SQL INTEGER OTS INTEGER
OCI_TYPECODE_REAL = 21;
SQL SIGNED INTEGER(32) OTS SINT32
OCI_TYPECODE_REF = SQLT_REF;
Type manager typecodes
- These are typecodes designed to be used with the type manager; they also include longer, more readable versions of existing SQLT names
- Those types that are directly related to existing SQLT types are #define'd to their SQLT equivalents
- The type manager typecodes are designed to be useable for all OCI calls. They are in the range from 192 to 320 for typecodes, so as not to conflict with existing OCI SQLT typecodes (see ocidfn.h)
OCI_TYPECODE_SIGNED16 = 28;
SQL SIGNED INTEGER(8) OTS SINT8
OCI_TYPECODE_SIGNED32 = 29;
SQL SIGNED INTEGER(16) OTS SINT16
OCI_TYPECODE_SIGNED8 = 27;
SQL DATE OTS DATE
OCI_TYPECODE_SMALLINT = 246;
SQL ??? OTS OCTET
OCI_TYPECODE_SYSFIRST = 228;
Last OTM typecode
OCI_TYPECODE_SYSLAST = 235;
First OTM system type (internal)
OCI_TYPECODE_TABLE = 248;
SQL VARRAY OTS PAGED VARRAY
OCI_TYPECODE_TIME = SQLT_TIME;
SQL/OTS CHARACTER FILE OBJECT the following are ANSI datetime datatypes added in 8.1
OCI_TYPECODE_TIMESTAMP = SQLT_TIMESTAMP;
SQL/OTS TIME_TZ
OCI_TYPECODE_TIMESTAMP_LTZ = SQLT_TIMESTAMP_LTZ;
SQL/OTS TIMESTAMP_TZ
OCI_TYPECODE_TIMESTAMP_TZ = SQLT_TIMESTAMP_TZ;
SQL/OTS TIMESTAMP
OCI_TYPECODE_TIME_TZ = SQLT_TIME_TZ;
SQL/OTS TIME
OCI_TYPECODE_UNSIGNED16 = 25;
SQL UNSIGNED INTEGER(8) OTS UINT8
OCI_TYPECODE_UNSIGNED32 = 26;
SQL UNSIGNED INTEGER(16) OTS UINT16
OCI_TYPECODE_UNSIGNED8 = SQLT_BIN;
SQL DECIMAL(P S) OTS DECIMAL(P S)
OCI_TYPECODE_UROWID = SQLT_RDD;
SQL/OTS INTRVL DAY-SEC
OCI_TYPECODE_VARCHAR = SQLT_CHR;
SQL CHAR(N) OTS SQL_CHAR(N)
OCI_TYPECODE_VARCHAR2 = SQLT_VCS;
SQL POINTER OTS POINTER
OCI_TYPECODE_VARRAY = 247;
OTS MLSLABEL
OCI_UTF8 = $367;
Defined here for overriding OCI_CHARSET_UTF8/OCI_CHARSET_WIN1252 if needed
| Functions or procedures | Description | |
|---|---|---|
| CharSetIDToCodePage | Return the system code page corresponding to an Oracle Charset code | |
| Int64ToSqlT_VNU | Conversion from a 64-bit integer to a raw VARNUM memory structure | |
| OracleCharSetName | Return the text name from an Oracle Charset code | |
| OracleLibraryInitialize | Try to load the Oracle Client Library | |
| SimilarCharSet | Check if two Oracle Charset codes are similar |
function CharSetIDToCodePage(aCharSetID: cardinal): cardinal;
Return the system code page corresponding to an Oracle Charset code
procedure Int64ToSqlT_VNU(Value: Int64; OutData: PSqlT_VNU);
Conversion from a 64-bit integer to a raw VARNUM memory structure
function OracleCharSetName(aCharsetID: cardinal): PUtf8Char;
Return the text name from an Oracle Charset code
procedure OracleLibraryInitialize(const LibraryFileName: TFileName = '');
Try to load the Oracle Client Library
- raise a ESqlDBOracle exception if loading failed
- you could then use the raw API functions via the OCI global variable
function SimilarCharSet(aCharset1, aCharset2: cardinal): boolean;
Check if two Oracle Charset codes are similar
OCI: TSqlDBOracleLib = nil;
Global variable used to access the Oracle Client Library once loaded
- call first OracleLibraryInitialize to load the library if needd
OCI_CHARSET_UTF8: cardinal = OCI_AL32UTF8;
The OCI charset used for UTF-8 encoding
- OCI_UTF8 is a deprecated encoding, and OCI_AL32UTF8 should be preferred
- but you can fallback for OCI_UTF8 for compatibility purposes
OCI_CHARSET_WIN1252: cardinal = OCI_WE8MSWIN1252;
The OCI charset used for WinAnsi encoding
SynDBOracleBlobChunksCount: ub4 = 250;
How many blob chunks should be handled at once
SynDBOracleOCIpath: TFileName;
Optional folder where the Oracle Client Library is to be searched
- by default, the oci.dll library is searched in the system PATH, then in %ORACLE_HOME%\bin
- you can specify here a folder name in which the oci.dll is to be found