Skip Headers

Oracle® Call Interface Programmer's Guide
10g Release 1 (10.1)

Part Number B10779-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Feedback

Go to previous page
Previous
Go to next page
Next
View PDF

12
Direct Path Loading

The direct path loading functions are used to load data from external files into tables and partitions.

This chapter contains these topics:

Direct Path Loading Overview

The direct path load interface enables an OCI application to access the direct path load engine of the Oracle database server to perform the functions of the Oracle SQL*Loader utility. This functionality provides the ability to load data from external files into either a table or a partition of a partitioned table.

Figure 12-1 Direct Path Loading

Text description of lnoci040.gif follows

Text description of the illustration lnoci040.gif

The OCI direct path load interface has the ability to load multiple rows by loading a direct path stream that contains data for multiple rows.

To use the direct path API, the client application performs the following steps:

  1. Perform the OCI initialization.
  2. Allocate a direct path context handle and set the attributes.
  3. Supply the name of the object (table, partition, or sub-partition) to be loaded.
  4. Describe the external datatypes of the columns of the object(s).
  5. Prepare the direct path interface.
  6. Allocate one or more column arrays.
  7. Allocate one or more direct path streams.
  8. Set entries in the column array to point to the input data value for each column.
  9. Convert a column array to a direct path stream format.
  10. Load the direct path stream.
  11. Retrieve any errors that may have occurred.
  12. Invoke the direct path finishing function.
  13. Free handles and data structures.
  14. Disconnect from the server.

Steps 8 through 11 can be repeated many times, depending on the data to be loaded.

A direct load operation requires that the object being loaded is locked to prevent DML on the object. Note that queries are lock-free and are allowed while the object is being loaded. The mode of the DML lock, and which DML locks are obtained depend upon the specification of the OCI_ATTR_DIRPATH_PARALLEL option, and if a partition or sub-partition load is being done as opposed to an entire table load.

See Also:

"OCI_ATTR_DIRPATH_PARALLEL"

Datatypes Supported for Direct Path Loading

The following external datatypes are valid for scalar columns in a direct path load operation:

The following external object datatypes are supported:

The following table types are supported:

Direct Path Handles

A direct path load corresponds to a direct path array insert operation. The direct path load interface uses the following handles to keep track of the objects loaded and the specification of the data operated on:

Direct Path Context

This handle must be allocated for each object, either a table or a partition of a partitioned table, being loaded. Because a OCIDirPathCtx handle is the parent handle of the OCIDirPathFuncCtx, OCIDirPathColArray, and OCIDirPathStream handles, freeing a OCIDirPathCtx handle frees its child handles also (although for good coding practices, free child handles individually before you free the parent handle).

A direct path context is allocated with OCIHandleAlloc(). Note that the parent handle of a direct path context is always the environment handle. A direct path context is freed with OCIHandleFree(). Include the header files in the first two lines in all direct path programs:

...
#include <cdemodp0.h>
#include <cdemodp.h>

OCIEnv *envp;
OCIDirPathCtx *dpctx;
sword error;
error = OCIHandleAlloc((dvoid *)envp, (dvoid **)&dpctx,
                    OCI_HTYPE_DIRPATH_CTX, (size_t)0,(dvoid **)0);
...

error = OCIHandleFree(dpctx, OCI_HTYPE_DIRPATH_CTX);

OCI Direct Path Function Context

See Also:

For more about the datatypes supported, see Oracle Database Application Developer's Guide - Object-Relational Features

This handle, of type OCIDirPathFuncCtx, is used to describe the following named type and REF columns:

The handle type OCI_HTYPE_DIRPATH_FN_CTX is passed to OCIHandleAlloc() to indicate that a function context is to be allocated, as in the following example.

OCIDirPathCtx *dpctx;       /* direct path context */
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */
sword error;

error = OCIHandleAlloc((dvoid *)dpctx, (dvoid **)&dpfnctx,
                       OCI_HTYPE_DIRPATH_FN_CTX,
                       (size_t)0, (dvoid **)0);

Note that the parent handle of a direct path function context is always the direct path context handle. A direct path function context handle is freed with:

error = OCIHandleFree(dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX);

Direct Path Column Array and Direct Path Function Column Array

These handles are used to present an array of rows to the direct path interface. A row is represented by three arrays: column values, column lengths, and column flags. Methods used on a column array include: allocate the array handle and set or get values corresponding to an array entry.

Both handles share the same data structure, OCIDirPathColArray. But these column array handles differ in parent handles and handle types.

A direct path column array handle is allocated with OCIHandleAlloc(). The following code fragment shows explicit allocation of the direct path column array handle:

OCIDirPathCtx *dpctx;      /* direct path context */
OCIDirPathColArray *dpca;  /* direct path column array */
sword error;
error = OCIHandleAlloc((dvoid *)dpctx, (dvoid **)&dpca,
               OCI_HTYPE_DIRPATH_COLUMN_ARRAY, 
               (size_t)0, (dvoid **)0);

A direct path column array handle is freed with OCIHandleFree().

error = OCIHandleFree(dpca, OCI_HTYPE_DIRPATH_COLUMN_ARRAY);

A direct path function column array handle is allocated in almost the same way:

OCIDirPathFuncCtx *dpfnctx;   /* direct path function context */
OCIDirPathColArray *dpfnca;   /* direct path function column array */
sword error;
error = OCIHandleAlloc((dvoid *)dpfnctx, (dvoid **)&dpfnca,
                        (ub4)OCI_HTYPE_DIRPATH_FN_COL_ARRAY,
                        (size_t)0, (dvoid **)0);

A direct path function column array is freed with OCIHandleFree():

error = OCIHandleFree(dpfnca, OCI_HTYPE_DIRPATH_FN_COL_ARRAY);

Freeing a OCIDirPathColArray handle also frees the column array associated with the handle.

Direct Path Stream

This handle is used by the conversion operation, OCIDirPathColArrayToStream(), and by the load operation, OCIDirPathLoadStream().

Direct path stream handles is allocated by the client with OCIHandleAlloc(). The structure of a OCIDirPathStream handle can be thought of as a pair in the form (buffer, buffer length).

A direct path stream is a linear representation of Oracle table data. The conversion operations always append to the end of the stream. Load operations always start from the beginning of the stream. After a stream is completely loaded, the stream must be reset by calling OCIDirPathStreamReset().

The following example shows a direct path stream handle allocated with OCIHandleAlloc(). The parent handle is always an OCIDirPathCtx handle:

OCIDirPathCtx *dpctx;    /* direct path context */
OCIDirPathStream *dpstr; /* direct path stream */
sword error;
error = OCIHandleAlloc((dvoid *)dpctx, (dvoid **)&dpstr,
               OCI_HTYPE_DIRPATH_STREAM, (size_t)0,(dvoid **)0);

A direct path stream handle is freed using OCIHandleFree().

error = OCIHandleFree(dpstr, OCI_HTYPE_DIRPATH_STREAM);

Freeing an OCIDirPathStream handle also frees the stream buffer associated with the handle.

Direct Path Interface Functions

The functions listed in this section are used with the direct path load interface.

See Also:

Detailed descriptions of each function can be found in "Direct Path Loading Functions"

Operations on the direct path context are performed by the functions in Table 12-1, "Direct Path Context Functions".

Table 12-1 Direct Path Context Functions  
Function Purpose

OCIDirPathAbort()

Aborts a direct path operation

OCIDirPathDataSave()

Executes a data savepoint

OCIDirPathFinish()

Commits the loaded data

OCIDirPathFlushRow()

Flushes a partial row from the database server

OCIDirPathLoadStream()

Loads data that has been converted to direct path stream format

OCIDirPathPrepare()

Prepares direct path interface to convert or load rows

Operations on the direct path column array are performed by the functions in Table 12-2, "Direct Path Column Array Functions".

Table 12-2 Direct Path Column Array Functions  
Function Purpose

OCIDirPathColArrayEntryGet()

Gets a specified entry in a column array

OCIDirPathColArrayEntrySet()

Sets a specified entry in a column array to a specific value

OCIDirPathColArrayRowGet()

Gets the base row pointers for a specified row number

OCIDirPathColArrayReset()

Resets the row array state

OCIDirPathColArrayToStream()

Converts from a column array format to a direct path stream format

Operations on the direct path stream are performed by the function OCIDirPathStreamReset() which resets the direct stream state.

Limitations and Restrictions of the Direct Path Load Interface

The direct path load interface has the following limitations that are the same as SQL*Loader:

Direct Path Load Example for Scalar Columns

Data Structures Used in Direct Path Loading Example

The following data structure is used in the example.

/* load control structure */
struct loadctl
{
  ub4                 nrow_ctl;            /* number of rows in column array */
  ub2                 ncol_ctl;         /* number of columns in column array */
  OCIEnv             *envhp_ctl;                       /* environment handle */
  OCIServer          *srvhp_ctl;                            /* server handle */
  OCIError           *errhp_ctl;                             /* error handle */
  OCIError           *errhp2_ctl;                /* yet another error handle */
  OCISvcCtx          *svchp_ctl;                          /* service context */
  OCISession         *authp_ctl;                   /* authentication context */
  OCIParam           *colLstDesc_ctl;        /* column list parameter handle */
  OCIDirPathCtx      *dpctx_ctl;                      /* direct path context */
  OCIDirPathColArray *dpca_ctl;           /* direct path column array handle */
  OCIDirPathColArray *dpobjca_ctl;          /* dp column array handle for obj*/
  OCIDirPathColArray *dpnestedobjca_ctl;  /* dp col array hndl for nested obj*/
  OCIDirPathStream   *dpstr_ctl;                /* direct path stream handle */
  ub1                *buf_ctl;    /* pre-alloc'd buffer for out-of-line data */
  ub4                 bufsz_ctl;                 /* size of buf_ctl in bytes */
  ub4                 bufoff_ctl;                     /* offset into buf_ctl */
  ub4                *otor_ctl;                  /* Offset to Recnum mapping */
  ub1                *inbuf_ctl;                 /* buffer for input records */
  struct pctx         pctx_ctl;                     /* partial field context */
  boolean             loadobjcol_ctl;             /* load to obj col(s)? T/F */
};

The header file cdemodp.h, which is from the demo directory, defines several structs:

#ifndef cdemodp_ORACLE
# define cdemodp_ORACLE

# include <oratypes.h>

# ifndef externdef
#  define externdef
# endif

/* External column attributes */
struct col
{
  text *name_col;                                             /* column name */
  ub2   id_col;                                            /* column load id */
  ub2   exttyp_col;                                         /* external type */
  text *datemask_col;                             /* datemask, if applicable */
  ub1   prec_col;                                /* precision, if applicable */
  sb1   scale_col;                                   /* scale, if applicable */
  ub2   csid_col;                                        /* character set id */
  ub1   date_col;            /* is column a chrdate or date? 1=TRUE. 0=FALSE */
  struct obj * obj_col;          /* description of object, if applicable */
#define COL_OID 0x1                                         /* col is an OID */
  ub4   flag_col;
};

/* Input field descriptor
 * For this example (and simplicity),
 * fields are strictly positional.
 */
struct fld
{
  ub4  begpos_fld;                             /* 1-based beginning position */
  ub4  endpos_fld;                             /* 1-based ending    position */
  ub4  maxlen_fld;                       /* max length for out of line field */
  ub4    flag_fld;
#define FLD_INLINE            0x1
#define FLD_OUTOFLINE         0x2
#define FLD_STRIP_LEAD_BLANK  0x4
#define FLD_STRIP_TRAIL_BLANK 0x8
};

struct obj
{
  text               *name_obj;                                /* type  name*/
  ub2                 ncol_obj;              /* number of columns in col_obj*/
  struct col         *col_obj;                          /* column attributes*/
  struct fld         *fld_obj;                           /* field descriptor*/
  ub4                 rowoff_obj;  /* current row offset in the column array*/
  ub4                 nrows_obj;              /* number of rows in col array*/
  OCIDirPathFuncCtx  *ctx_obj;       /* Function context for this obj column*/
  OCIDirPathColArray *ca_obj;           /* column array  for this obj column*/
  ub4                 flag_obj;                              /* type of obj */
#define OBJ_OBJ  0x1                                             /* obj col */
#define OBJ_OPQ  0x2                                  /* opaque/sql str col */
#define OBJ_REF  0x4                                             /* ref col */
};

struct tbl
{
  text        *owner_tbl;                                     /* table owner */
  text        *name_tbl;                                       /* table name */
  text        *subname_tbl;                        /* subname, if applicable */
  ub2          ncol_tbl;                     /* number of columns in col_tbl */
  text        *dfltdatemask_tbl;            /* table level default date mask */
  struct col  *col_tbl;                                 /* column attributes */
  struct fld  *fld_tbl;                                  /* field descriptor */
  ub1          parallel_tbl;                         /* parallel: 1 for true */
  ub1          nolog_tbl;                          /* no logging: 1 for true */
  ub4          xfrsz_tbl;                   /* transfer buffer size in bytes */
  text         *objconstr_tbl;   /* obj constr/type if loading a derived obj */
};

struct sess                        /* options for a direct path load session */
{
  text        *username_sess;                                        /* user */
  text        *password_sess;                                    /* password */
  text        *inst_sess;                            /* remote instance name */
  text        *outfn_sess;                                /* output filename */
  ub4          maxreclen_sess;          /* max size of input record in bytes */
};


#endif                                              /* cdemodp_ORACLE */

Outline of an Example of a Direct Path Load for Scalar Columns

The following sample code illustrates the use of several of the OCI direct path interfaces. It is not a complete code example.

The init_load function performs a direct path load using the direct path API on the table described by tblp. The loadctl structure given by ctlp has an appropriately initialized environment and service context. A connection has been made to the server.


STATICF void
init_load(ctlp, tblp)
struct loadctl *ctlp;
struct tbl     *tblp;
{
  struct  col   *colp;
  struct  fld   *fldp;
  sword          ociret;                       /* return code from OCI calls */
  OCIDirPathCtx *dpctx;                               /* direct path context */
  OCIParam      *colDesc;                     /* column parameter descriptor */
  ub1            parmtyp;
  ub1           *timestamp = (ub1 *)0;
  ub4            size;
  ub4            i;
  ub4            pos;

  /* allocate and initialize a direct path context */
  /* See cdemodp.c for the definition of OCI_CHECK */
  OCI_CHECK(ctlp->envhp_ctl, OCI_HTYPE_ENV, ociret, ctlp,
            OCIHandleAlloc((dvoid *)ctlp->envhp_ctl,
                           (dvoid **)&ctlp->dpctx_ctl,
                           (ub4)OCI_HTYPE_DIRPATH_CTX,
                           (size_t)0, (dvoid **)0));

  dpctx = ctlp->dpctx_ctl;                                      /* shorthand */

  OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp,
            OCIAttrSet((dvoid *)dpctx, (ub4)OCI_HTYPE_DIRPATH_CTX,
                       (dvoid *)tblp->name_tbl,
                       (ub4)strlen((const char *)tblp->name_tbl),
                       (ub4)OCI_ATTR_NAME, ctlp->errhp_ctl));

Additional attributes, such as OCI_ATTR_SUB_NAME and OCI_ATTR_SCHEMA_NAME, are also set here. After the attributes have been set, prepare the load.

  OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp,
            OCIDirPathPrepare(dpctx, ctlp->svchp_ctl, ctlp->errhp_ctl));
Allocate the Column Array and Stream Handles.

Note that the direct path context handle is the parent handle for the column array and stream handles. Also note that errors are returned with the environment handle associated with the direct path context.


   OCI_CHECK(ctlp->envhp_ctl, OCI_HTYPE_ENV, ociret, ctlp,
            OCIHandleAlloc((dvoid *)ctlp->dpctx_ctl, (dvoid **)&ctlp->dpca_ctl,
                           (ub4)OCI_HTYPE_DIRPATH_COLUMN_ARRAY,
                           (size_t)0, (dvoid **)0));

  OCI_CHECK(ctlp->envhp_ctl, OCI_HTYPE_ENV, ociret, ctlp,
            OCIHandleAlloc((dvoid *)ctlp->dpctx_ctl,(dvoid **)&ctlp->dpstr_ctl,
                           (ub4)OCI_HTYPE_DIRPATH_STREAM,
                           (size_t)0, (dvoid **)0));
Get Number of Rows and Columns

Get number of rows and columns in the column array just allocated.


  OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp,
            OCIAttrGet(ctlp->dpca_ctl, (ub4)OCI_HTYPE_DIRPATH_COLUMN_ARRAY,
                       &ctlp->nrow_ctl, 0, OCI_ATTR_NUM_ROWS,
                       ctlp->errhp_ctl));

   OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp,
            OCIAttrGet(ctlp->dpca_ctl, (ub4)OCI_HTYPE_DIRPATH_COLUMN_ARRAY,
                       &ctlp->ncol_ctl, 0, OCI_ATTR_NUM_COLS,
                       ctlp->errhp_ctl));
Set Input Data Fields

Set the input data fields to their corresponding data columns.

ub4            rowoff;                          /* column array row offset */
ub4            clen;                                      /* column length */
ub1            cflg;                                  /* column state flag */
ub1           *cval;                             /* column character value */

OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp,
            OCIDirPathColArrayEntrySet(ctlp->dpca_ctl, ctlp->errhp_ctl,
                                       rowoff, colp->id_col,
                                       cval, clen, cflg));
Reset Column Array State

Reset column array state in case a previous conversion needed to be continued or a row is expecting more data.

(void) OCIDirPathColArrayReset(ctlp->dpca_ctl, ctlp->errhp_ctl);
Reset the Stream State

Reset the stream state to start a new stream. Otherwise, data in the stream is appended to existing data.

(void) OCIDirPathStreamReset(ctlp->dpstr_ctl, ctlp->errhp_ctl);
Convert Data to Stream Format

After inputting the data, convert the data in the column array to stream format and filter out any bad records.

ub4            rowcnt;                   /* number of rows in column array */
ub4            startoff;         /* starting row offset into column array  */

/* convert array to stream, filter out bad records */
ocierr = OCIDirPathColArrayToStream(ctlp->dpca_ctl, ctlp->dpctx_ctl,
                                        ctlp->dpstr_ctl, ctlp->errhp_ctl,
                                        rowcnt, startoff);
Load the Stream.

Note that the position in the stream is maintained internally to the stream handle, along with offset information for the column array which produced the stream. When the conversion to stream format is done, the data is appended to the stream. It is the responsibility of the caller to reset the stream when appropriate. On errors, the position is moved to the next row, or the end of the stream if the error occurs on the last row. The next OCIDirPathLoadStream() call starts on the next row, if any. If a OCIDirPathLoadStream() call is made, and the end of a stream has been reached, OCI_NO_DATA is returned.

/* load the stream */
ociret = OCIDirPathLoadStream(ctlp->dpctx_ctl, ctlp->dpstr_ctl,
            ctlp->errhp_ctl);
Finish the Direct Path Load
/* free up server data structures for the load */
OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp,
          OCIDirPathFinish(ctlp->dpctx_ctl, ctlp->errhp_ctl));
Free the Direct Path Handles

Free all the direct path handles allocated. Note that direct path column array and stream handles are freed before the parent direct path context handle is freed.

ociret = OCIHandleFree((dvoid *)ctlp->dpca_ctl,
                           OCI_HTYPE_DIRPATH_COLUMN_ARRAY);
ociret = OCIHandleFree((dvoid *)ctlp->dpstr_ctl,
                           OCI_HTYPE_DIRPATH_STREAM);
ociret = OCIHandleFree((dvoid *)ctlp->dpctx_ctl, 
                          OCI_HTYPE_DIRPATH_CTX);

Using a Date Cache in Direct Path Loading of Dates in OCI

The date cache feature provides improved performance when loading Oracle date and timestamp values that require datatype conversions in order to be stored in the table.

This feature is specifically targeted to loads where the same input date values are loaded over and over again. Date conversions are very expensive and can account for a large percentage of the total load time, especially if there are multiple date columns loaded. This feature can significantly improve performance by reducing the actual number of date conversions done when many duplicate date values occur in the input data. However, date cache will only improve performance when many duplicate input date values are loaded into date columns (the word date in this chapter applies to all the date and timestamp datatypes).

When you explicitly specify the date cache size, the date cache feature will not be disabled, by default. To override this behavior, set OCI_ATTR_DIRPATH_DCACHE_DISABLE to 1. Otherwise, the cache will continue to be searched to avoid date conversions. However any misses will be converted the hard way.

Query the attributes OCI_ATTR_DIRPATH_DCACHE_NUM, OCI_ATTR_DIRPATH_DCACHE_MISSES, OCI_ATTR_DIRPATH_DCACHE_HITS and then tune the cache size for future loads.

You can lower the cache size when there are no misses and the number of elements in the cache is less than the cache size. The cache size can be increased if there are many cache misses and relatively few hits. Note that increasing the cache size too much can cause other problems, like paging or exhausting memory. If increasing the cache size does not improve performance, the feature should not be used.

The date cache feature can be explicitly and totally disabled by setting the date cache size to 0.

The following OCI direct path context attributes support this functionality:

OCI_ATTR_DIRPATH_DCACHE_SIZE

This attribute, when not equal to 0, sets the date cache size (in elements) for a table. For example, if the date cache size is set to 200, then at most 200 unique date or timestamp values can be stored in the cache. The date cache size cannot be changed once OCIDirPathPrepare() has been called. The default value is 0, meaning a date cache will not be created for a table. A date cache will be created for a table only if one or more date or timestamp values are loaded that require datatype conversions and the attribute value is nonzero.

OCI_ATTR_DIRPATH_DCACHE_NUM

This attribute is used to query the current number of entries in a date cache.

OCI_ATTR_DIRPATH_DCACHE_MISSES

This attribute is used to query the current number of date cache misses. If this number is high, consider tuning the application with a larger date cache size. If increasing the date cache size doesn't cause this number to decrease significantly, the date cache should probably not be used. Date cache misses are expensive, due to hashing and look up times.

OCI_ATTR_DIRPATH_DCACHE_HITS

This attribute is used to query the number of date cache hits. This number should be relatively large in order to see any benefit of using the date cache support.

OCI_ATTR_DIRPATH_DCACHE_DISABLE

Setting this attribute to 1 indicates that the date cache should be disabled if the size is exceeded. Note that this attribute cannot be changed or set after OCIDirPathPrepare() has been called.

The default (= 0) is to not disable a cache on overflow. When not disabled, the cache is searched to avoid conversions, but overflow input date value entries will not be added to the date cache, and will be converted using expensive date conversion functions. Again, excessive date cache misses can cause the application to run slower than not using the date cache at all.

This attribute can also be queried to see if a date cache has been disabled due to overflow.

See Also:

"Direct Path Context Handle (OCIDirPathCtx) Attributes"

Direct Path Loading of Object Types

The use of the direct path function contexts to load various non-scalar types is discussed in this section.

The non-scalar types are:

Direct Path Loading of Nested Tables

Nested tables are stored in a separate table. Using the direct path loading API, a nested table is loaded separately from its parent table with a foreign key, called a SETID, to link the two tables together.


Note:
  • Currently, the SETIDs must be user-supplied, and are not system-generated.
  • When loading the parent and child tables separately, it is possible that orphaned children can be created when the rows are inserted in the child table, but the corresponding parent row is not inserted in the parent table. It is also possible to insert a parent row in the parent table, but that the child rows are not inserted in the child table and therefore it will have missing children.

Describing a Nested Table Column and Its Nested Table


Note:

Steps that are different from loading scalar data are in italics.


Loading the parent table with a nested table column is a separate action from loading the child nested table.

Direct Path Loading of Column Objects

A column object is a table column that is defined as an object. Currently only the default constructor, which consists of all of the constituent attributes, is supported.

Describing a Column Object

To describe a column object and its object attributes, use a direct path function context. Describing a column object requires setting its object constructor. Describing object attributes is similar to describing a list of scalar columns.

To describe a column object:


Note:
  • Nested column objects are supported.
  • The steps here are similar to that of describing a list of scalar columns to be loaded for a table. Steps that are new are in italics.

1. Allocate a parameter handle on the column object with OCI_DTYPE_PARAM. This parameter handle is used to set the column's external attributes.

2. Set the column name and its other external column attributes (for example, maximum data size, precision, scale).

3. Set the external type as SQLT_NTY (named type) with OCI_ATTR_DATA_TYPE.

4. Allocate a direct path function context handle. This context will be used to describe the column's object type and attributes:

OCIDirPathFuncCtx *dpfnctx  /* direct path function context */;
sword error;
error = OCIHandleAlloc((dvoid *)dpctx, (dvoid **)&dpfnctx,
               OCI_HTYPE_DIRPATH_FN_CTX, 
               (size_t)0, (dvoid **)0);

5. Set the column's object type name (for example, "Employee") with OCI_ATTR_NAME in the function context:

OCIDirPathFuncCtx *dpfnctx; /* direct path function context */
text *obj_type;   /* column object's object type */
sword error;

error = OCIAttrSet((dvoid *)dpfnctx,
                   OCI_HTYPE_DIRPATH_FN_CTX,
                   (dvoid *)obj_type, (ub4)strlen((const char *)obj_type),
                   OCI_ATTR_NAME, ctlp->errhp_ctl);

6. Set the expression type, OCI_ATTR_DIRPATH_EXPR_TYPE, to be OCI_DIRPATH_EXPR_OBJ_CONSTR. This indicates that the expression set with OCI_ATTR_NAME will be used as the default object constructor:

OCIDirPathFuncCtx *dpfnctx; /* direct path function context */
ub1 expr_type = OCI_DIRPATH_EXPR_OBJ_CONSTR;
sword error;

error = OCIAttrSet((dvoid *)dpfnctx,
                   OCI_HTYPE_DIRPATH_FN_CTX,
                   (dvoid *)&expr_type, (ub4)0,
                   OCI_ATTR_DIRPATH_EXPR_TYPE,
                   ctlp->errhp_ctl);

7. Set the number of columns or object attributes that will be loaded for this column object using OCI_ATTR_NUM_COLS.

8. Get the column/attribute parameter list for the function context OCIDirPathFuncCtx.

9. For each object attribute:

10. Set the function context OCIDirPathFuncCtx that was created in step 4 into the parent column object's parameter handle with OCI_ATTR_DIRPATH_FN_CTX.

Allocating the Array Column for the Column Object

When loading a column object, the data for its object attributes will be loaded into a separate column array created just for that object. A child column array is allocated for each column object, whether it is nested or not. Each row of object attributes in the child column array maps back to the corresponding non-NULL row of its parent column object in the parent column array.

Use the column object's direct path function context handle and column array type OCI_HTYPE_DIRPATH_FN_COL_ARRAY.

To allocate a child column array for a column object:

OCIDirPathFuncCtx *dpfnctx; /* direct path function context */
OCIDirPathColArray *dpfnca;   /* direct path function column array */
sword error;

error = OCIHandleAlloc((dvoid *)dpfnctx, (dvoid **)&dpfnca,
                       OCI_HTYPE_DIRPATH_FN_COL_ARRAY,
                       (size_t)0, (dvoid **)0);

Loading Column Object Data into the Column Array

If a column is scalar, its value is set in the column array by passing the address of its value to OCIDirPathColArrayEntrySet(). And if a column is an object, the address of its child column array handle is passed instead. The child column array will contain the data of the object attributes.

To load data into a column object:


Note:

Steps that are different from loading scalar data are in italics.


(Start.) For each column object:

  1. If the column is non-NULL:
    1. For each of its object attribute columns:

      If an object attribute is a nested column object, then go to (Start.) and do this entire procedure recursively.

      Set the data in the child column array using OCIDirPathColArrayEntrySet().

    2. Set the column object's data in the column array by passing the address of its child column array handle to OCIDirPathColArrayEntrySet().
  2. Else if the column is NULL:
    • Set the column object's data in the column array by passing a NULL address for the data, a length of 0, and an OCI_DIRPATH_COL_NULL flag to OCIDirPathColArrayEntrySet().

Direct Path Loading of SQL String Columns

A column value can be computed by a SQL string. SQL strings can be used for scalar column types. SQL strings cannot be used for object types, but can be used for object attributes of scalar column types. They cannot be used for nested tables and LONGs.

A SQL expression is represented to the direct path API using the OCIDirPathFuncCtx. Its OCI_ATTR_NAME value will be the SQL string with the parameter list of the named bind variables for the expression.

A SQL string example is:

substr(substr(:string, :offset, :length), :offset, :length)

Things to note about this example are:

Describing a SQL String Column


Note:

Steps that are different from loading scalar data are in italics.



  1. Allocate a parameter handle on the SQL string column with OCI_DTYPE_PARAM. This parameter handle is used to set the column's external attributes.
  2. Set the column name and its other external column attributes (for example, maximum data size, precision, scale).
  3. Set the SQL string column's external type as SQLT_NTY with OCI_ATTR_DATA_TYPE.
  4. Allocate a direct path function context handle. This context will be used to describe the arguments of the SQL string.
    OCIDirPathFuncCtx *dpfnctx  /* direct path function context */;
    sword error;
    error = OCIHandleAlloc((dvoid *)dpctx, (dvoid **)&dpfnctx,
                   OCI_HTYPE_DIRPATH_FN_CTX, 
                   (size_t)0, (dvoid **)0);
    
    
  5. Set the column's SQL string in OCI_ATTR_NAME in the function context.
    OCIDirPathFuncCtx *dpfnctx; /* direct path function context */
    text *sql_str;   /* column's SQL string expression */
    sword error;
    
    error = OCIAttrSet((dvoid *)dpfnctx,
                       OCI_HTYPE_DIRPATH_FN_CTX,
                       (dvoid *)sql_str, (ub4)strlen((const char *)sql_str),
                       OCI_ATTR_NAME, ctlp->errhp_ctl);
    
    
  6. Set the expression type, OCI_ATTR_DIRPATH_EXPR_TYPE, to be OCI_DIRPATH_EXPR_SQL. This indicates that the expression set with OCI_ATTR_NAME will be used as the SQL string to derive the value from.
    OCIDirPathFuncCtx *dpfnctx; /* direct path function context */
    ub1 expr_type = OCI_DIRPATH_EXPR_SQL;
    sword error;
    
    error = OCIAttrSet((dvoid *)dpfnctx,
                       OCI_HTYPE_DIRPATH_FN_CTX,
                       (dvoid *)&expr_type, (ub4)0,
                       OCI_ATTR_DIRPATH_EXPR_TYPE, ctlp->errhp_ctl);
    
    
  7. Set the number of arguments that will be passed to the SQL string with OCI_ATTR_NUM_COLS.
  8. Get the column/attribute parameter list for the function context.
  9. For each SQL string argument: