Oracle® Database XStream Guide 11g Release 2 (11.2) Part Number E15874-01 |
|
|
View PDF |
This chapter describes the XStream functions for OCI. XStream stands for eXtended Streams. LCR stands for Logical Change Record.
Row LCR is used to encapsulate each row change. It includes the schema name, table name, DML operation, and the column values. For update operations, both before and after column values are included. The column data is in the format specified by the "Program Variable" column in Table 12-3. Character columns are converted to the client's character set.
DDL LCR is used to encapsulate DDL changes. It includes the object name, the DDL text, and the DDL command, for example, ALTER
TABLE
, and TRUNCATE
TABLE
command. See Oracle Call Interface Programmer's Guide for a list of DDL command codes.
See Also:
Oracle Database Globalization Support Guide for more information about NLS settings.XStream example programs are found in xstream/oci
under the demo directory.
Each LCR also has a transaction id and position. For transactions captured outside Oracle databases, any byte-comparable RAW
array can be used as the LCR position, if the position of each LCR in the stream is strictly increasing.
This chapter contains the topic:
The functions are described using the following conventions:
A description of each of the function's parameters. This includes the parameter's mode. The mode of a parameter has three possible values, as described in Table 12-1:
This section describes the OCI XStream functions.
Table 12-2 OCI XStream Functions
Function | Purpose |
---|---|
LCR |
To get and set value of an LCR. Note: These calls do not require a server round trip. |
Returns existing extra attributes from the LCR. |
|
Sets extra attributes in a ROW or DDL LCR. |
|
Frees the LCR. |
|
Returns the common header fields for ROW/DDL LCR. |
|
Initializes the common header fields for ROW or DDL LCR. |
|
Retrieves specific fields in a DDL LCR. |
|
Populates DDL-specific fields in a DDL LCR. |
|
Returns the LOB information for a piece-wise LOB LCR. |
|
Sets the LOB information for a piece-wise LOB LCR. |
|
Constructs a new Streams LCR object of the specified type (ROW or DDL) for the given duration. |
|
Returns the column fields in a ROW LCR. |
|
Populates column fields in a ROW LCR. |
|
Returns the generated SQL statement for the row LCR, with values in-lined. |
|
Returns the generated SQL statement, which uses bind variables for column values. |
|
Gets the SCN and commit SCN from a position value. |
|
Converts SCN to position. |
|
Gets the |
|
Gets the |
|
XStream In |
To send an LCR stream to an XStream inbound server. |
Attaches to an inbound server. |
|
Sends chunk data to the inbound server. |
|
Detaches from the inbound server. |
|
Flushes the network while attaching to an XStream inbound server. |
|
Sends the LCR stream to the attached inbound server using callbacks. |
|
Sends the LCR stream to the attached inbound server using callbacks. |
|
Gets the local processed low-position. |
|
XStream Out |
To receive an LCR stream from an XStream outbound server. |
Attaches to an outbound server. |
|
Retrieves data of each LOB or |
|
Detaches from the outbound server. |
|
Gets the LCR stream from the outbound server using callbacks. |
|
Receives an LCR stream from an outbound server without using callbacks. |
|
Updates the local copy of the processed low-water mark. |
Purpose
This function gets extra attribute information in (ROW or DDL) LCR, and any non-first class attributes that are not populated through OCILCRHeaderGet()
, OCILCRDDLInfoGet()
, or OCILCRRowColumnInfoGet()
, for example, edition name.
Syntax
sword OCILCRAttributesGet ( OCISvcCtx *svchp, OCIError *errhp, ub2 *num_attrs oratext **attr_names, ub2 *attr_namesl, ub2 *attr_dtyp, void **attr_valuesp, OCIInd *attr_indp, ub2 *attr_alensp, void *lcrp, ub2 array_size, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Number of extra attributes.
An array of extra attribute name pointers.
An array of extra attribute name lengths.
An array of extra attribute data types. Valid data types: see Comments.
An array of extra attribute data value pointers.
An indicator array. Each returned element is an OCIInd
value (OCI_IND_NULL
or OCI_IND_NOTNULL
).
An array of actual extra attribute data lengths. Each element in alensp
is the length in bytes.
Pointer to ROW or DDL LCR.
Size of the array argument in the other parameters. If array_size
is not large enough to accommodate the number of attributes in the requested attribute list then OCI_ERROR
is returned. Parameter num_attrs
returns the expected size.
Specify OCI_DEFAULT
for now.
Comments
The valid data types for attr_dtyp
are:
SQLT_CHR SQLT_INT SQLT_RDD
Purpose
This function populates extra attribute information in ROW or DDL LCR, and any non-first class attributes that cannot be set through OCILCRHeaderSet()
, OCILCRDDLInfoSet()
, or OCILCRRowColumnInfoSet()
, for example. edition name.
Syntax
sword OCILCRAttributesSet ( OCISvcCtx *svchp, OCIError *errhp, ub2 num_attrs oratext **attr_names, ub2 *attr_names_lens, ub2 *attr_dtyp, void **attr_valuesp, OCIInd *attr_indp, ub2 *attr_alensp, void *lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Number of extra attributes.
Pointer to an array of extra attribute names. Attribute names must be canonicalized.
Pointer to an array of extra attribute name lengths.
Pointer to an array of extra attribute data types. See valid data types in Comments of "OCILCRRowColumnInfoSet()".
Address of an array of extra attribute data values.
Pointer to an indicator array. For all data types, this is a pointer to an array of OCIInd
values (OCI_IND_NULL
or OCI_IND_NOTNULL
).
Pointer to an array of actual extra attribute data lengths. Each element in attr_lensp
is the length in bytes.
Pointer to a ROW or DDL LCR.
Specify OCI_DEFAULT
for now.
Comments
Valid attributes are:
#define OCI_LCR_ATTR_THREAD_NO "THREAD#" #define OCI_LCR_ATTR_ROW_ID "ROW_ID" #define OCI_LCR_ATTR_SESSION_NO "SESSION#" #define OCI_LCR_ATTR_SERIAL_NO "SERIAL#" #define OCI_LCR_ATTR_USERNAME "USERNAME" #define OCI_LCR_ATTR_TX_NAME "TX_NAME" #define OCI_LCR_ATTR_EDITION_NAME "EDITION_NAME" #define OCI_LCR_ATTR_MESSAGE_TRACKING_LABEL "MESSAGE_TRACKING_LABEL"
Purpose
Frees the LCR.
Syntax
sword OCILCRFree ( OCISvcCtx *svchp, OCIError *errhp, void *lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Streams LCR pointer.
Specify OCI_DEFAULT
for now.
Purpose
Retrieves specific fields in a DDL LCR.
Syntax
sword OCILCRDDLInfoGet ( OCISvcCtx *svchp, OCIError *errhp, oratext **object_type, ub2 *object_type_len, oratext **ddl_text, ub4 *ddl_text_len, oratext **logon_user, ub2 *logon_user_len, oratext **current_schema, ub2 *current_schema_len, oratext **base_table_owner, ub2 *base_table_owner_len, oratext **base_table_name, ub2 *base_table_name_len, oraub8 *flag, void *ddl_lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
The type of object on which the DDL statement was executed. (See OCILCRDDLInfoSet()
). Optional -- if not NULL
then both object_type
and object_type_len
arguments must not be NULL
.
Length of the object_type
string without the NULL
terminator.
The text of the DDL statement. Optional. If not NULL
then both ddl_text
and ddl_text_len
arguments must not be NULL
.
DDL text length in bytes without the NULL
terminator.
Canonicalized (follows a rule or procedure) name of the user whose session executed the DDL statement. Optional. If not NULL
then both logon_user
and logon_user_len
arguments must not be NULL
.
Length of the logon_user string without the NULL
terminator.
The canonicalized schema name that is used if no schema is specified explicitly for the modified database objects in ddl_text
. Optional. If not NULL
then both current_schema
and current_schema_len
arguments must not be NULL
.
Length of the current_schema
string without the NULL
terminator.
If the DDL statement is a table-related DDL (such as CREATE
TABLE
and ALTER
TABLE
), or if the DDL statement involves a table (such as creating a trigger on a table), then base_table_owner
specifies the canonicalized owner of the table involved. Otherwise, base_table_owner
is NULL
. Optional -- if not NULL
then both base_table_owner
and base_table_owner_len
arguments must not be NULL
.
Length of the base_table_owner
string without the NULL
terminator.
If the DDL statement is a table-related DDL (such as CREATE
TABLE
and ALTER
TABLE
), or if the DDL statement involves a table (such as creating a trigger on a table), then base_table_name
specifies the canonicalized name of the table involved. Otherwise, base_table_name
is NULL
. Optional -- if not NULL
then both base_table_name
and base_table_name_len
arguments must not be NULL
.
Length of the base_table_name
string without the NULL
terminator.
DDL LCR flag. Optional. Data not returned if argument is NULL
. Future extension not used currently.
DDL LCR. Cannot be NULL
.
Specify OCI_DEFAULT
for now.
Purpose
Returns the common header fields for ROW or DDL LCR. All returned pointers point directly to the corresponding LCR fields.
Syntax
sword OCILCRHeaderGet ( OCISvcCtx *svchp, OCIError *errhp, oratext **src_db_name, ub2 *src_db_name_len, oratext **cmd_type, ub2 *cmd_type_len, oratext **owner, ub2 *owner_len, oratext **oname, ub2 *oname_len, ub1 **tag, ub2 *tag_len, oratext **txid, ub2 *txid_len, OCIDate *src_time, ub2 *old_columns, ub2 *new_columns, ub1 **position, ub2 *position_len, oraub8 *flag, void *lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Canonicalized source database name. Must be non-NULL
.
Length of the src_db_name
string in bytes excluding the NULL
terminator.
For ROW LCRs: One of the following values:
#define OCI_LCR_ROW_CMD_INSERT #define OCI_LCR_ROW_CMD_DELETE #define OCI_LCR_ROW_CMD_UPDATE #define OCI_LCR_ROW_CMD_COMMIT #define OCI_LCR_ROW_CMD_LOB_WRITE #define OCI_LCR_ROW_CMD_LOB_TRIM #define OCI_LCR_ROW_CMD_LOB_ERASE
For DDL LCRs: One of the command types in Oracle Call Interface Programmer's Guide.
Length of the cmd_type
string in bytes excluding the NULL
terminator.
Canonicalized table owner name. Must be non-NULL
.
Length of the owner
string in bytes excluding the NULL
terminator.
Canonicalized table name. Must be non-NULL
Length of the oname
string in bytes excluding the NULL
terminator.
A binary tag that enables tracking of the LCR. For example, this tag can be used to determine the original source database of the DML statement if apply forwarding is used.
Number of bytes in the tag.
Transaction ID. Must be non-NULL
Length of the string in bytes excluding the NULL
terminator.
The time when the change was generated in the redo log of the source database.
Number of columns in the OLD column list. Returns 0 if the input LCR is a DDL LCR. Optional.
Number of columns in the NEW column list. Returns 0 if the input LCR is a DDL LCR. Optional.
Position for LCR.
Length of position
.
LCR flag. Future extension currently not used.
lcrp
cannot be NULL
.
OCILCR_NEW_ONLY_MODE
- If this mode is specified then the new_columns
returned is the count of the columns in the NEW column list only. Otherwise, the new_columns
returned is the number of distinct columns present in either the NEW or the OLD column list of the given ROW LCR.
Purpose
Returns the generated SQL statement for the row LCR, with values in-lined. Users must preallocate the memory for sql_stmt
, and *sql_stmt_len
must be set to the size of the allocated buffer, when it is passed in. If *sql_stmt_len
is not large enough to hold the generated SQL statement, then an error is raised.
Syntax
sword OCILCRRowStmtGet ( OCISvcCtx *svchp, OCIError *errhp, oratext *row_stmt, ub4 *row_stmt_len, void *row_lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
The generated SQL statement for the ROW LCR.
Set to the size of the allocated buffer for row_stmt
when passed in; returns the length of row_stmt
.
Pointer to ROW LCR.
Specify OCI_DEFAULT
for now.
Purpose
Returns the generated SQL statement, which uses bind variables for column values. The values for the bind variables are returned separately in arrays. You must preallocate the memory for sql_stmt
and the arrays, *sql_stmt_len
must be set to the size of the allocated buffer, and array_size
must be the length of the arrays. The actual column values in bind_var_valuesp
will point to the values inside the LCR, so it is a shallow copy. If array_size
is not large enough to hold all the variables, or *sql_stmt_len
is not large enough to hold the generated SQL statement, then an error is raised.
Syntax
sword OCILCRRowStmtWithBindVarGet ( OCISvcCtx *svchp, OCIError *errhp, oratext *row_stmt, ub4 *row_stmt_len, ub2 *num_bind_var, ub2 *bind_var_dtyp, void **bind_var_valuesp, OCIInd *bind_var_indp, ub2 *bind_var_alensp, ub1 *bind_var_csetidp, ub1 *bind_var_csetfp, void *row_lcrp, oratext **chunk_column_names, ub2 *chunk_column_namesl, oraub8 *chunk_column_flags, ub2 array_size, oratext *bind_var_syntax, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
The generated SQL statement for the ROW LCR.
Set to the size of the allocated buffer for row_stmt
when passed in; returns the length of row_stmt
.
The number of bind variables.
Array of data types for the bind variables.
Array of values for the bind variables.
Array of NULL
indicators for the bind variables.
Array of lengths for the bind variable values.
Array of character set ids for the bind variables.
Array of character set forms for the bind variables.
Pointer to ROW LCR.
Array of LOB column names in LCR.
Array of LOB column name lengths.
Array of LOB column flags. Possible flags are listed in Comments.
Size of each of the parameter arrays.
Either ":" (binds will be of the form :1, :2, and so on.) or "?" (binds will be of the form "?").
Specify OCI_DEFAULT
for now.
Comments
LCR column flags can be combined using bitwise OR
operator.
#define OCI_LCR_COLUMN_LOB_DATA /* column contains LOB data */ #define OCI_LCR_COLUMN_LONG_DATA /* column contains long data */ #define OCI_LCR_COLUMN_EMPTY_LOB /* column has an empty LOB */ #define OCI_LCR_COLUMN_LAST_CHUNK /* last chunk of current column */ #define OCI_LCR_COLUMN_AL16UTF16 /* column is in AL16UTF16 fmt */ #define OCI_LCR_COLUMN_NCLOB /* column has NCLOB data */ #define OCI_LCR_COLUMN_XML_DATA /* column contains xml data */ #define OCI_LCR_COLUMN_XML_DIFF /* column contains xmldiff data */ #define OCI_LCR_COLUMN_ENCRYPTED /* column is encrypted */ #define OCI_LCR_COLUMN_UPDATED /* col is updated */ /* OCI_LCR_COLUMN_UPDATED is set only for the modified columns in the NEW * column list of an update LCR. */
Purpose
Constructs a new Streams LCR object of the specified type (ROW or DDL) for the given duration.
Syntax
sword OCILCRNew ( OCISvcCtx *svchp, OCIError *errhp, OCIDuration duration, ub1 lcrtype, void **lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Memory for the LCR is allocated for this specified duration.
LCR type. Values are:
#define OCI_LCR_XROW #define OCI_LCR_XDDL
If *lcrp
is not NULL
, an error will be raised.
Specify OCI_DEFAULT
for now.
Comments
Note:
Once created, you will not be allowed to change the type of the LCR (ROW or DDL) or duration of the memory allocation.
Use OCILCRHeaderSet()
to populate common header fields for ROW or DDL LCR.
After the LCR header is initialized, use OCILCRRowColumnInfoSet()
or OCILCRDDLInfoSet()
to populate operation specific elements. Use OCILCRExtraAttributesSet()
to populate extra attribute information.
Use OCILCRFree()
to free the LCR created by this function.
Purpose
Returns the column fields in a ROW LCR.
Syntax
sword OCILCRRowColumnInfoGet ( OCISvcCtx *svchp, OCIError *errhp, ub2 column_value_type, ub2 *num_columns, oratext **column_names, ub2 *column_name_lens, ub2 *column_dtyp, void **column_valuesp, OCIInd *column_indp, ub2 *column_alensp, ub1 *column_csetfp, oraub8 *column_flags, ub2 *column_csid, void *row_lcrp, ub2 array_size, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
ROW LCR column value type; either of:
#define OCI_LCR_ROW_COLVAL_OLD #define OCI_LCR_ROW_COLVAL_NEW
Number of columns in the specified column array.
An array of column name pointers.
An array of column name lengths.
An array of column data types. Optional. Data is not returned if column_dtyp
is NULL
.
An array of column data pointers.
An array of indicators.
An array of column lengths. Each returned element is the length in bytes.
An array of character set forms for the columns. Optional. Data is not returned if the argument is NULL
.
An array of column flags. Optional. Data is not returned if the argument is NULL
. See Comments for the values.
An array of character set ids for the columns.
row_lcrp
cannot be NULL
.
Size of each of the parameter arrays. An error is returned if array_size
is less than the number of columns in the requested column list. The actual size of the requested column list is returned through the num_columns
parameter.
OCILCR_NEW_ONLY_MODE
- If this mode is specified then the new_columns
returned is the count of the columns in the NEW column list only. Otherwise, the new_columns
returned is the number of distinct columns present in either the NEW or the OLD column list of the given ROW LCR.
Comments
For INSERT
, this function must only be called to get the NEW column values.
For DELETE
, this function must only be called to get the OLD column values.
For UPDATE
, this function can be called twice, once to get the NEW column values and once to get the OLD column values.
This function must not be called for COMMIT
operations.
LCR column flags. Can be combined using bitwise OR
operator.
#define OCI_LCR_COLUMN_LOB_DATA /* column contains LOB data */ #define OCI_LCR_COLUMN_LONG_DATA /* column contains long data */ #define OCI_LCR_COLUMN_EMPTY_LOB /* column has an empty LOB */ #define OCI_LCR_COLUMN_LAST_CHUNK /* last chunk of current column */ #define OCI_LCR_COLUMN_AL16UTF16 /* column is in AL16UTF16 fmt */ #define OCI_LCR_COLUMN_NCLOB /* column has NCLOB data */ #define OCI_LCR_COLUMN_XML_DATA /* column contains xml data */ #define OCI_LCR_COLUMN_XML_DIFF /* column contains xmldiff data */ #define OCI_LCR_COLUMN_ENCRYPTED /* column is encrypted */ #define OCI_LCR_COLUMN_UPDATED /* col is updated */ /* OCI_LCR_COLUMN_UPDATED is set only for the modified columns in the NEW * column list of an update LCR. */
The following chart lists the currently supported table column data types. For each data type, it lists the corresponding LCR column data type, the C program variable type to cast the LCR column value, and the OCI functions that can be used to manipulate the column values returned from OCILCRRowColumnInfoGet()
.
Table 12-3 Table Column Data Types
Table Column Data Types | LCR Column Data Type | Program Variable | Conversion Function |
---|---|---|---|
VARCHAR, NVARCHAR2 |
SQLT_CHR |
char * |
|
NUMBER |
SQLT_VNU |
OCINumber |
OCINumberToInt(), OCINumberToReal(), OCINumberToText() |
DATE |
SQLT_ODT |
OCIDate |
OCIDateToText() Can access structure directly to get date and time fields. |
RAW |
SQLT_BIN |
unsigned char * |
|
CHAR, NCHAR |
SQLT_AFC |
char * |
|
BINARY_FLOAT |
SQLT_BFLOAT |
float |
|
BINARY_DOUBLE |
SQLT_BDOUBLE |
double |
|
TIMESTAMP |
SQLT_TIMESTAMP |
OCIDateTime * |
OCIDateTimeGetTime() OCIDateTimeGetDate() OCIDateTimeGetTimeZoneOffset() OCIDateTimeToText() |
TIMESTAMP WITH TIME ZONE |
SQLT_TIMESTAMP_TZ |
OCIDateTime * |
OCIDateTimeGetTime() OCIDateTimeGetDate() OCIDateTimeGetTimeZoneOffset() OCIDateTimeToText() |
TIMESTAMP WITH LOCAL TIME ZONE |
SQLT_TIMESTAMP_LTZ |
OCIDateTime * |
OCIDateTimeGetTime()OCIDateTimeGetDate()OCIDateTimeGetTimeZoneOffset()OCIDateTimeToText() |
INTERVAL YEAR TO MONTH |
SQLT_INTERVAL_YM |
OCIInterval * |
OCIIntervalToText() OCIIntervalGetYearMonth() |
INTERVAL DAY TO SECOND |
SQLT_INTERVAL_DS |
OCIInterval * |
OCIIntervalToText()OCIIntervalGetDaySecond() |
UROWID |
SQLT_RDD |
OCIRowid * |
OCIRowidToChar() |
CLOB |
SQLT_CHR or SQLT_BIN |
unsigned char * |
* |
NCLOB |
SQLT_BIN |
unsigned char * |
* |
BLOB |
SQLT_BIN |
unsigned char * |
* |
LONG |
SQLT_CHR |
char * |
* |
LONG RAW |
SQLT_BIN |
unsigned char * |
* |
* Call OCIXStreamOutChunkReceive() to get column data.
Purpose
Populates column fields in a ROW LCR.
Syntax
sword OCILCRRowColumnInfoSet ( OCISvcCtx *svchp, OCIError *errhp, ub2 column_value_type, ub2 num_columns, oratext **column_names, ub2 *column_name_lens, ub2 *column_dtyp, void **column_valuesp, OCIInd *column_indp, ub2 *column_alensp, ub1 *column_csetfp, oraub8 *column_flags, ub2 *column_csid, void *row_lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
ROW LCR Column value types:
#define OCI_LCR_ROW_COLVAL_OLD #define OCI_LCR_ROW_COLVAL_NEW
Number of columns in each of the array parameters.
Pointer to an array of column names. Column names must be canonicalized. Column names must follow Oracle naming conventions and size limitations.
Pointer to an array of column name lengths.
Pointer to an array of column data types. See Comments for valid data types.
Pointer to an array of column data pointers.
Pointer to an indicator array. For all data types, this is a pointer to an array of OCIInd
values (OCI_IND_NULL
or OCI_IND_NOTNULL
).
Pointer to an array of actual column lengths in bytes.
Pointer to an array of character set forms for the columns. The default form is SQLCS_IMPLICIT
. Setting this attribute will cause the database or national character set to be used on the client side. Set this attribute to SQLCS_NCHAR
for the national character set or SQLCS_IMPLICIT
for the database character set. Pass 0 for non-character columns.
Pointer to an array of column flags. (See Comments for the list of valid LCR column flags.)
Pointer to an array of character set ids for the columns.
row_lcrp
cannot be NULL
.
Specify OCI_DEFAULT
for now.
Comments
Note:
For INSERT
, this function must only be called to specify the NEW column values.
For DELETE
, this function must only be called to specify the OLD column values.
For UPDATE
, this function can be called twice, once to specify the NEW column values and once to specify the OLD column values.
This function must not be called for COMMIT
operations.
Here are the LCR column flags. They can be combined using the bitwise OR
operator.
#define OCI_LCR_COLUMN_LOB_DATA /* column contains LOB data */ #define OCI_LCR_COLUMN_LONG_DATA /* column contains long data */ #define OCI_LCR_COLUMN_EMPTY_LOB /* column has an empty LOB */ #define OCI_LCR_COLUMN_LAST_CHUNK /* last chunk of current column */ #define OCI_LCR_COLUMN_AL16UTF16 /* column is in AL16UTF16 fmt */ #define OCI_LCR_COLUMN_NCLOB /* column has NCLOB data */ #define OCI_LCR_COLUMN_XML_DATA /* column contains xml data */ #define OCI_LCR_COLUMN_XML_DIFF /* column contains xmldiff data */ #define OCI_LCR_COLUMN_ENCRYPTED /* column is encrypted */ #define OCI_LCR_COLUMN_UPDATED /* col is updated */ /* OCI_LCR_COLUMN_UPDATED is set only for the modified columns in the NEW * column list of an update LCR. */
Valid data types are:
SQLT_AFC SQLT_TIMESTAMP SQLT_DAT SQLT_TIMESTAMP_TZ SQLT_BFLOAT SQLT_TIMESTAMP_LTZ SQLT_BDOUBLE SQLT_INTERVAL_YM SQLT_NUM SQLT_INTERVAL_DS SQLT_VCS SQLT_ODT SQLT_INT SQLT_BIN SQLT_CHR SQLT_RDD SQLT_VST SQLT_INT SQLT_FLT
Purpose
Populates DDL-specific fields in a DDL LCR.
Syntax
sword OCILCRDDLInfoSet ( OCISvcCtx *svchp, OCIError *errhp, oratext *object_type, ub2 object_type_len, oratext *ddl_text, ub4 ddl_text_len, oratext *logon_user, ub2 logon_user_len, oratext *current_schema, ub2 current_schema_len, oratext *base_table_owner, ub2 base_table_owner_len, oratext *base_table_name, ub2 base_table_name_len, oraub8 flag, void *ddl_lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
The type of object on which the DDL statement was executed. See Comments for the valid object types.
Length of the object_type
string without the NULL
terminator.
The text of the DDL statement. This parameter must be set to a non-NULL
value. DDL text must be in Oracle DDL format.
DDL text length in bytes without the NULL
terminator.
Canonicalized name of the user whose session executed the DDL statement.
Length of the logon_user
string without the NULL
terminator. Must follow Oracle naming conventions and size limitations.
The canonicalized schema name that is used if no schema is specified explicitly for the modified database objects in ddl_text
. If a schema is specified in ddl_text
that differs from the one specified for current_schema
, then the function uses the schema specified in ddl_text
.
This parameter must be set to a non-NULL
value.
Length of the current_schema
string without the NULL
terminator. Must follow Oracle naming conventions and size limitations.
If the DDL statement is a table-related DDL (such as CREATE
TABLE
or ALTER
TABLE
), or if the DDL statement involves a table (such as creating a trigger on a table), then base_table_owner
specifies the canonicalized owner of the table involved. Otherwise, base_table_owner
is NULL
.
Length of the base_table_owner
string without the NULL
terminator. Must follow Oracle naming conventions and size limitations.
If the DDL statement is a table-related DDL (such as CREATE
TABLE
or ALTER
TABLE
), or if the DDL statement involves a table (such as creating a trigger on a table), then base_table_name
specifies the canonicalized name of the table involved. Otherwise, base_table_name
is NULL
.
Length of the base_table_name
without the NULL
terminator. Must follow Oracle naming conventions and size limitations.
DDL LCR flag. (For future extension – specify OCI_DEFAULT
for now)
ddl_lcrp
cannot be NULL
.
Specify OCI_DEFAULT
for now.
Comments
The following are valid object types:
CLUSTER FUNCTION INDEX OUTLINE PACKAGE PACKAGE BODY PROCEDURE SEQUENCE SYNONYM TABLE TRIGGER TYPE USER VIEW
NULL
is also a valid object type. Specify NULL
for all object types not listed.
Purpose
Initializes the common header fields for ROW or DDL LCR.
Syntax
sword OCILCRHeaderSet ( OCISvcCtx *svchp, OCIError *errhp, oratext *src_db_name, ub2 src_db_name_len, oratext *cmd_type, ub2 cmd_type_len, oratext *owner, ub2 owner_len, oratext *oname, ub2 oname_len, ub1 *tag, ub2 tag_len, oratext *txid, ub2 txid_len, OCIDate *src_time, ub1 *position, ub2 position_len, oraub8 flag, void *lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Canonicalized source database name. Must be non-NULL
.
Length of the src_db_name
string in bytes excluding the NULL
terminator. Must follow Oracle naming conventions and size limitations.
For ROW LCRs: One of the following values:
#define OCI_LCR_ROW_CMD_INSERT #define OCI_LCR_ROW_CMD_DELETE #define OCI_LCR_ROW_CMD_UPDATE #define OCI_LCR_ROW_CMD_COMMIT #define OCI_LCR_ROW_CMD_LOB_WRITE #define OCI_LCR_ROW_CMD_LOB_TRIM #define OCI_LCR_ROW_CMD_LOB_ERASE
For DDL LCRs: One of the command types in Oracle Call Interface Programmer's Guide.
Length of cmd_type
.
Canonicalized table owner name. Owner is not required for COMMIT
LCR.
Length of the owner
string in bytes excluding the NULL
terminator. Must follow Oracle naming conventions and size limitations.
Canonicalized table name. Owner is not required for COMMIT
LCR.
Length of the oname
string in bytes excluding the NULL
terminator. Must follow Oracle naming conventions and size limitations.
A binary tag that enables tracking of the LCR. For example, this tag can be used to determine the original source database of the DML statement if apply forwarding is used.
Number of bytes in the tag. Cannot exceed 2000 bytes.
Transaction ID. Must be non-NULL
.
Length of the txid
string in bytes, excluding the NULL
terminator. Must follow Oracle naming conventions and size limitations.
The time when the change was generated in the redo log of the source database.
Position for LCR. Must be non-NULL
and byte-comparable.
Length of position. Must be greater than zero.
LCR flag. Future extension not used currently.
lcrp
cannot be NULL
.
Specify OCI_DEFAULT
for now.
Comments
Note:
This function will set all internal fields of the LCR to NULL
including extra attributes.
This function does not deep copy the passed-in values. You must ensure data is valid for the duration of the LCR.
For COMMIT
LCRs, owner
and oname
information are not required. Provide valid values for src_db_name
, cmd_type
, tag
, txid
, and position
.
For ROW LCRs, use OCILCRRowColumnInfoSet()
to populate ROW LCR specific-column information.
For DDL LCRs, use OCILCRDDLInfoSet()
to populate DDL operation specific information.
For Row or DDL LCRs, use OCILCRAttributesSet()
to populate extra attribute information.
Purpose
Returns the LOB information for a piece-wise LOB LCR generated from a DBMS_LOB
or OCILob
procedure.
Syntax
sword OCILCRLobInfoGet ( OCISvcCtx *svchp, OCIError *errhp, oratext **column_name, ub2 *column_name_len, ub2 *column_dty, oraub8 *column_flag, ub4 *offset, ub4 *size, void *row_lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
LOB column name.
Length of LOB column name.
Column data type (either SQLT_CHR
or SQLT_BIN
).
Column flag. See Comments in "OCILCRRowColumnInfoSet()".
LOB operation offset in code points. Only returned for LOB
WRITE
and LOB
TRIM
operations. This is the same as the offset
parameter for OCILobErase()
or the offset
parameter in OCILobWrite()
.
LOB operation size in code points. Only returned for LOB
TRIM
and LOB
ERASE
operations.This is the same as the new_length
parameter in OCILobTrim()
or the amtp
parameter in OCILobErase()
.
Pointer to a ROW LCR.
Specify OCI_DEFAULT
for now.
Comments
Returns OCI_SUCCESS
or OCI_ERROR
.
Purpose
Sets the LOB information for a piece-wise LOB LCR. This call is valid when the input LCR is a LOB_WRITE
, LOB_ERASE
or LOB_TRIM
; otherwise, an error is returned.
Syntax
sword OCILCRLobInfoSet ( OCISvcCtx *svchp, OCIError *errhp, oratext *column_name, ub2 column_name_len, ub2 column_dty, oraub8 column_flag, ub4 offset, ub4 size, void *row_lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
LOB column name.
Length of LOB column name.
Column data type (either SQLT_CHR
or SQLT_BIN
).
Column flag. See Comments in "OCILCRRowColumnInfoSet()".
LOB operation offset in code points. Only required for LOB
WRITE
and LOB
TRIM
operations. This is the same as the soffset
parameter for OCILobErase()
or the offset
parameter in OCILobWrite()
.
LOB operation size in code points. Only required for LOB
TRIM
and LOB
ERASE
operations.This is the same as the new_length
parameter in OCILobTrim()
or the amtp
parameter in OCILobErase()
.
Pointer to a ROW LCR.
Specify OCI_DEFAULT
for now.
Comments
Returns OCI_SUCCESS
or OCI_ERROR
.
Purpose
Returns the SCN and the commit SCN from the position value. The input position must be one that is obtained from an XStream outbound server. An error is returned if the input position does not conform to the expected format.
Syntax
sword OCILCRSCNsFromPosition ( OCISvcCtx *svchp, OCIError *errhp, ub1 *position, ub2 position_len, OCINumber *scn, OCINumber *commit_scn, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
LCR position value.
Length of LCR position value.
SCN number embedded in the given LCR position.
The commit SCN embedded in the given position.
Mode flags for future expansion. Specify OCI_DEFAULT
for now.
Purpose
Converts an SCN to a position. The generated position can be passed as the last_position
to OCIXStreamOutAttach()
to filter the LCRs with commit SCN less than the given SCN and the LCR's SCN less than the given SCN. Therefore, the first LCR sent by the outbound server is either:
1. A commit LCR at the given SCN, or
2. The first LCR of the subsequent transaction with commit SCN greater than or equal to the given SCN.
Syntax
sword OCILCRSCNToPosition ( OCISvcCtx *svchp, OCIError *errhp, ub1 *position, ub2 *position_len, OCINumber *scn, ub4 mode );
Parameters
OCI service context.
OCI error handle.
The resulting position. You must preallocate OCI_LCR_MAX_POSITION_LEN
bytes.
Length of position
.
The SCN to be stored in position
.
Mode flags (for future extension).
Comments
Returns OCI_SUCCESS
if the conversion succeeds, OCI_ERROR
otherwise.
Purpose
Gets the WHERE
clause statement for the given ROW LCR.
Syntax
sword OCILCRWhereClauseGet ( OCISvcCtx *svchp, OCIError *errhp, oratext *wc_stmt, ub4 *wc_stmt_len, void *row_lcrp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
SQL statement equivalent to the LCR.
Length of the wc_stmt
buffer.
Row LCR to be converted to SQL.
Mode flags for future expansion. For now, specify OCI_DEFAULT
.
Comments
WHERE
clause generated for an INSERT
LCR will have all the columns that are being inserted. This WHERE
clause could be used to identify the inserted row after inserting. (Like "returning ROWID
").
INSERT INTO TAB(COL1) VALUES (10) -> WHERE COL1=10
WHERE
clause generated for UPDATE
will have all the columns in the old column list. However the values of the columns will be that of the new value if it exists in the new column list of the UPDATE
. If the column does not have a new value then the old column value will be used.
UPDATE TAB SET COL1 = 10 WHERE COL1 = 20 -> WHERE COL1 = 10 UPDATE TAB SET COL2 = 20 WHERE COL1 = 20 -> WHERE COL1 = 20
WHERE
clause for DELETE will use the columns and values from the old column list.
LOB piecewise operations use the new columns and values for generating the WHERE
clause.
Returns
OCI_SUCCESS
or OCI_ERROR
.
Purpose
Gets the WHERE
clause statement with bind variables for the given ROW LCR.
Syntax
sword OCILCRWhereClauseWithBindVarGet ( OCISvcCtx *svchp, OCIError *errhp, oratext *wc_stmt, ub4 *wc_stmt_len, ub2 *num_bind_var, ub2 *bind_var_dtyp, void **bind_var_valuesp, OCIInd *bind_var_indp, ub2 *bind_var_alensp, ub2 *bind_var_csetidp, ub1 *bind_var_csetfp, void *row_lcrp, ub2 array_size, oratext *bind_var_syntax, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
SQL statement equivalent to the LCR.
Length of the wc_stmt
buffer.
Number of bind variables.
Array of data types of bind variables.
Array of values of bind variables.
Array of NULL
indicators of bind variables.
Array of lengths of bind values.
Array of char set ids of binds.
Array of char set forms of binds.
Row LCR to be converted to SQL.
Size of the array of bind values.
Native syntax to be used for binds.
Mode flags for future expansion. For now, specify OCI_DEFAULT
.
Comments
If array_size
is not large enough to accommodate the number of columns in the requested column list then OCI_ERROR
is returned. The expected array_size
is returned through the num_bind_var
parameter.
bind_var_syntax
for Oracle Database should contain ":". This will generate positional binds such as :1, :2, :3, and so on. For non-Oracle databases input the string that needs to be used for binds.
The WHERE
clause generated for INSERT
LCR will have all the columns that are being inserted. This WHERE
clause can be used to identify the inserted row after inserting. (like "returning ROWID
").
INSERT INTO TAB(COL1) VALUES (10) -> WHERE COL1=10
The WHERE
clause generated for UPDATE
will have all the columns in the old column list. However the values of the columns will be that of the new column value of the column if it exists in the new values of the UPDATE
. If the column appears only in the old column then the old column value will be used.
UPDATE TAB SET COL1 = 10 WHERE COL1 = 20 -> WHERE COL1 = 10 UPDATE TAB SET COL2 = 20 WHERE COL1 = 20 -> WHERE COL1 = 20
The WHERE
clause for DELETE
will use the columns and values from the old column list.
LOB piecewise operations will use the new columns and values for generating the WHERE
clause.
Returns
OCI_SUCCESS
or OCI_ERROR
.
Purpose
Attaches to an inbound server.
Syntax
sword OCIXStreamInAttach ( OCISvcCtx *svchp, OCIError *errhp, oratext *server_name, ub2 server_name_len, oratext *source_name, ub2 source_name_len, ub1 *last_position, ub2 *last_position_len, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
XStream inbound server name.
Length of the XStream inbound server name.
Source name to identify the data source.
Source name length.
Last position received by inbound server. Optional. If specified, then you must preallocate OCI_LCR_MAX_POSITION_LEN
bytes for the return value.
Length of last_position
. Must be non-NULL
if last_position
is non-NULL
.
Specify OCI_DEFAULT
for now.
Comments
The name of the inbound server must be provided because multiple inbound servers can be configured in one Oracle instance. This function returns OCI_ERROR
if any error encountered while attaching to the inbound server. Only one client can attach to an XStream inbound server at any time. An error is returned if multiple clients attempt to attach to the same inbound server or if the same client attempts to attach to multiple inbound servers concurrently.
This function returns the last position received by the inbound server. Having successfully attached to the server, the client should resume sending LCRs with positions greater than this last_position
since the inbound server will discard all LCRs with positions less than or equal to the last_position
.
Returns either OCI_SUCCESS
or OCI_ERROR
status code.
Purpose
Detaches from the inbound server.
Syntax
sword OCIXStreamInDetach ( OCISvcCtx *svchp, OCIError *errhp, ub1 *processed_low_position, ub2 *processed_low_position_len ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
The server's processed low position.
Length of processed_low_position
.
Specify OCI_DEFAULT
for now.
Comments
You must pass in a preallocated buffer for the position argument. The maximum length of this buffer is OCI_LCR_MAX_POSITION_LEN
. This position is exposed in DBA_XSTREAM_INBOUND_PROGRESS
view
This call returns the server's processed low-position. If this function is invoked while a OCIXStreamInLCRSend()
call is in progress, then it immediately terminates that call before detaching from the inbound server.
Returns either OCI_SUCCESS
or OCI_ERROR
status code.
Purpose
Sends an LCR stream from the client to the attached inbound server. To avoid a network round trip for every OCIXStreamInLCRSend()
call, we will tie the connection to this call and terminate the call after ACK interval since we initiate the LCR stream to the server.
Syntax
sword OCIXStreamInLCRSend ( OCISvcCtx *svchp, OCIError *errhp, void *lcrp, ub1 lcrtype, oraub8 flag, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Pointer to the new LCR to send. It cannot be NULL
.
LCR type. Either of:
#define OCI_LCR_XROW #define OCI_LCR_XDDL
If bit OCI_XSTREAM_MORE_ROW_DATA
(0x01) is set, it means this LCR contains more chunk data. You must call OCIXStreamInChunkSend()
before calling OCIXStreamInLCRSend()
again.
Specify OCI_DEFAULT
for now.
Comments
Return codes are:
OCI_STILL_EXECUTING
means that the current call is still in progress. The connection associated with the specified service context handle is still tied to this call for streaming the LCRs to the server. An error is returned if you attempt to use the same connection to execute any OCI calls that require database round trip, for example, OCIStmtExecute()
, OCIStmtFetch()
, OCILobRead()
, and so on. OCILCR*
calls are local calls; thus, they are valid while this call is in progress.
OCI_SUCCESS
means the current call is completed. You can execute OCIStmt*
, OCILob*
, and so on from the same service context.
OCI_ERROR
means this call encounters some errors. Use OCIErrorGet()
to obtain information about the error.
See Also:
"Server Handle Attributes"Purpose
Sends an LCR stream to the attached inbound server. You must specify a callback to construct each LCR for streaming. If some LCRs contain chunk data, then a second callback must be provided to create each chunk data.
Syntax
sword OCIXStreamInLCRCallbackSend ( OCISvcCtx *svchp, OCIError *errhp, OCICallbackXStreamInLCRCreate createlcr_cb, OCICallbackXStreamInChunkCreate createchunk_cb, void *usrctxp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Client callback procedure to be invoked to generate an LCR for streaming. Cannot be NULL
.
Client callback procedure to be invoked to create each chunk. Can be NULL
if you do not need to send any LCR with LOB or LONG
or XMLType
columns. OCI_ERROR
will be returned if this argument is NULL
and you attempt to send an LCR with additional chunk data.
User context to pass to both callback functions.
Specify OCI_DEFAULT
fore now.
Comments
Return code: OCI_ERROR
or OCI_SUCCESS
.
The createlcr_cb
argument must be of type OCICallbackXStreamInLCRCreate
:
typedef sb4 (*OCICallbackXStreamInLCRCreate) void *usrctxp, void **lcrp, ub1 *lcrtyp, oraub8 *flag);
Parameters of OCICallbackXStreamInLCRCreate()
:
Pointer to the user context.
Pointer to the LCR to be sent.
LCR type (OCI_LCR_XROW
or OCI_LCR_XDDL
).
If OCI_XSTREAM_MORE_ROW_DATA
is set, then the current LCR has more chunk data.
The input parameter to the callback is the user context. The output parameters are the new LCR, its type, and a flag. If the generated LCR contains additional chunk data then this flag must have OCI_XSTREAM_MORE_ROW_DATA
(0x01) bit set. The valid return codes from OCICallbackXStreamInLCRCreate()
callback function are OCI_CONTINUE
or OCI_SUCCESS
. This callback function must return OCI_CONTINUE
to continue processing OCIXStreamInLCRCallbackSend()
call. Any return code other than OCI_CONTINUE
signals that the client wants to terminate OCIXStreamInLCRCallbackSend()
call immediately. In addition, a NULL
LCR returned from OCICallbackXStreamInLCRCreate()
callback function signals that the client wants to terminate the current call.
The createchunk_cb
argument must be of type OCICallbackXStreamInChunkCreate
:
typedef sb4 (*OCICallbackXStreamInChunkCreate) void *usrctxp, oratext **column_name, ub2 *column_name_len, ub2 *column_dty, oraub8 *column_flag, ub2 *column_csid, ub4 *chunk_bytes, ub1 **chunk_data, oraub8 *flag);
The input parameters of the createchunk_cb()
procedure are the user context and the information about the chunk.
Parameters of OCICallbackXStreamInChunkCreate()
:
Pointer to the user context.
Column name of the current chunk.
Length of the column name.
Chunk data type (SQLT_CHR
or SQLT_BIN
).
See Comments in "OCIXStreamInChunkSend()".
Column character set id. Relevant only if the column is an XMLType
column (that is, column_flag
has OCI_LCR_COLUMN_XML_DATA
bit set).
Chunk data length in bytes.
Chunk data pointer.
If OCI_XSTREAM_MORE_ROW_DATA
is set, this means the current LCR has more chunk data.
The OCIXStreamInLCRCallbackSend()
function will invoke createlcr_cb()
procedure to obtain each LCR to send to the server. If the return flag from the createlcr_cb()
procedure has OCI_XSTREAM_MORE_ROW_DATA
bit set, then it will invoke createchunk_cb()
procedure to obtain each chunk. It repeatedly calls createchunk_cb()
procedure while the flag returned from this callback has OCI_XSTREAM_MORE_ROW_DATA
bit set. When this bit is not set, this function will cycle back to invoke createlcr_cb()
procedure to get the next LCR. This cycle is repeated until the createlcr_cb()
procedure returns a NULL
LCR or when at the transaction boundary after an ACK interval has elapsed since the call begins.
The valid return codes from OCICallbackXStreamInChunkCreate()
callback function are OCI_CONTINUE
or OCI_SUCCESS
. This callback function must return OCI_CONTINUE
to continue processing OCIXStreamInLCRCallbackSend()
call. Any return code other than OCI_CONTINUE
signals that the client wants to terminate OCIXStreamInLCRCallbackSend()
call immediately.
Since terminating the current call will flush the network and incur another network round trip in the next call, you must avoid returning a NULL
LCR immediately when there is no LCR to send. Doing this can greatly reduce network throughput and affect performance. During short idle period, you can add some delays in the callback procedure instead of returning a NULL
LCR immediately to avoid flushing the network too frequently.
The following figure shows the execution flow of the OCIXStreamInLCRCallbackSend()
function:
Figure 12-1 Execution Flow of the OCIXStreamInLCRCallbackSend() Function
* While OCI_XSTREAM_MORE_ROW_DATA
is set
Description of the figure:
At 1, the user invokes OCIXStreamInLCRCallbackSend()
providing two callbacks. This function initiates an LCR inbound stream to the server.
At 2, this function invokes createlcr_cb()
procedure to get an LCR from the callback to send to the server. If the return LCR is NULL
then this function exits.
If the flag from 2 indicates the current LCR has more data (that is, OCI_XSTREAM_MORE_ROW_DATA
bit is set) then this function proceeds to 3; otherwise, it loops back to 2 to get the next LCR.
At 3, this function invokes createchunk_cb()
to get the chunk data to send to the server. If the flag from this callback has OCI_XSTREAM_MORE_ROW_DATA
bit set, then it repeats 3; otherwise, it loops back to 2 to get the next LCR from the user. If any callback function returns any values other than OCI_CONTINUE
then the OCIXStreamInLCRCallbackSend()
call terminates.
Following is a sample client pseudocode snippet for callback mode (error checking is not included for simplicity):
main { /* Attach to inbound server */ OCIXStreamInAttach(); /* Get the server's processed low-position to determine * the position of the first LCR to generate. */ OCIXStreamInProcessedLWMGet(&lwm); while (TRUE) { /* Initiate LCR inbound stream */ OCIXStreamInLCRCallbackSend(createlcr_cb, createchunk_cb); OCIXStreamInProcessedLWMGet(&lwm); if (some terminating condition) break; } OCIXStreamInDetach(&lwm); } createlcr_cb (IN usrctx, OUT lcr, OUT flag) { if (have more LCRs to send) { /* construct lcr */ OCILCRHeaderSet(lcr); OCILCRRowColumnInfoSet(lcr); if (lcr has LOB | LONG | XMLType columns) Set OCI_XSTREAM_MORE_ROW_DATA flag; if (lcr is LOB_ERASE | LOB_TRIM | LOB_WRITE) OCILCRLobInfoSet(lcr); } else if (idle timeout expires) { lcr = null; } } createchunk_cb (IN usrctx, OUT chunk, OUT flag) { /* set col_name, col_flag, chunk data, etc. */ construct_chunk; if (last chunk of current column) { set col_flag |= OCI_LCR_COLUMN_LAST_CHUNK; if (last column) clear OCI_XSTREAM_MORE_ROW_DATA flag; } }
Purpose
Gets the local processed low-position that is cached at the client. It can be called anytime while the client is attached to an XStream inbound server. Clients, using the callback mode to stream LCRs to the server (see "OCIXStreamInLCRCallbackSend()"), can invoke this function while in the callback procedures.
Syntax
sword OCIXStreamInProcessedLWMGet ( OCISvcCtx *svchp, OCIError *errhp, ub1 *processed_low_position, ub2 *processed_low_position_len, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
The processed low position maintained at the client.
Length of processed_low_position
.
Specify OCI_DEFAULT
for now.
Comments
After attaching to an XStream inbound server, a local copy of the server's processed low-position (see "OCIXStreamOutProcessedLWMSet()") is cached at the client. This local copy is refreshed with the server's low-position when each of the following calls returns OCI_SUCCESS
:
OCIXStreamInAttach()
OCIXStreamInLCRSend()
OCIXStreamInLCRCallbackSend()
OCIXStreamInFlush()
Return code: OCI_ERROR
or OCI_SUCCESS
.
You must pass in a preallocated buffer for the position argument. The maximum length of this buffer is OCI_LCR_MAX_POSITION_LEN
. This position is exposed in the DBA_XSTREAM_INBOUND_PROGRESS
view.
The client can use this position to periodically purge the logs used to generate the LCRs at or below this position.
Purpose
Used to flush the network while attaching to an XStream inbound server. It terminates any in-progress OCIXStreamInLCRSend()
call associated with the specified service context.
Syntax
sword OCIXStreamInFlush ( OCISvcCtx *svchp, OCIError *errhp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Specify OCI_DEFAULT
for now.
Comments
Return code: OCI_ERROR
or OCI_SUCCESS
.
Each call will incur a database round trip to get the server's processed low-position, which you can retrieve afterward using OCIXStreamInProcessedLWMGet()
. This function should be called only when there is no LCR to send to the server and the client wants to know the progress of the attached inbound server.
This call returns OCI_ERROR
if it is invoked from the callback functions of OCIXStreamInLCRCallbackSend()
.
Purpose
Sends a chunk to the inbound server. This function is valid during the execution of the OCIXStreamInLCRSend()
call.
Syntax
sword OCIXStreamInChunkSend ( OCISvcCtx *svchp, OCIError *errhp, oratext *column_name, ub2 column_name_len, ub2 column_dty, oraub8 column_flag, ub2 column_csid, ub4 chunk_bytes, ub1 *chunk_data, oraub8 flag, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Name of column associated with the given data. Column name must be canonicalized and must follow Oracle naming convention.
Length of column name.
LCR chunk data type (must be SQLT_CHR
or SQLT_BIN
). See Table 12-5, "Storage of LOB or LONG Data in the LCR"
Column flag. (See Comments for valid column flags). Must specify OCI_LCR_COLUMN_LAST_CHUNK
for the last chunk of each LOB or LONG
or XMLType
column.
Column character set id. This is required only if the column_flag
has OCI_LCR_COLUMN_XML_DATA
bit set.
Chunk data length in bytes.
Pointer to column data chunk. If the column is NCLOB
or varying width CLOB
, the input chunk data must be in AL16UTF16
format. The chunk data must be in the character set defined in "Storage of LOB or LONG Data in the LCR".
If OCI_XSTREAM_MORE_ROW_DATA
(0x01) bit is set, it means the current row change contains more data. You must clear this bit when sending the last chunk of the current LCR.
Specify OCI_DEFAULT
for now.
Comments
LCR column flags. Can be combined using bitwise OR
operator.
#define OCI_LCR_COLUMN_LOB_DATA /* column contains LOB data */ #define OCI_LCR_COLUMN_LONG_DATA /* column contains long data */ #define OCI_LCR_COLUMN_EMPTY_LOB /* column has an empty LOB */ #define OCI_LCR_COLUMN_LAST_CHUNK /* last chunk of current column */ #define OCI_LCR_COLUMN_AL16UTF16 /* column is in AL16UTF16 fmt */ #define OCI_LCR_COLUMN_NCLOB /* column has NCLOB data */ #define OCI_LCR_COLUMN_XML_DATA /* column contains xml data */ #define OCI_LCR_COLUMN_XML_DIFF /* column contains xmldiff data */ #define OCI_LCR_COLUMN_ENCRYPTED /* column is encrypted */ #define OCI_LCR_COLUMN_UPDATED /* col is updated */
In Streams, LOB, LONG
, or XMLType
column data is broken up into multiple chunks. For a row change containing columns of these data types, its associated LCR only contains data for the other column types. All LOB, LONG
or XMLType
columns are either represented in the LCR as NULL
or not included in the LCR as defined in Table 12-4, "Required Column List in the First LCR".
OCILCRRowColumnInfoSet()
is provided to generate a list of scalar columns in an LCR. For LOB, LONG
, and XMLType
columns, OCIXStreamInChunkSend()
is provided to set the value of each chunk in a column. For a large column, this function can be invoked consecutively multiple times with smaller chunks of data. The XStream inbound server can assemble these chunks and apply the accumulated change to the designated column.
The LCR of a row change must contain all the scalar columns which can uniquely identify a row at the apply site. Table 12-4 describes the required column list in each LCR for each DML operation.
Table 12-4 Required Column List in the First LCR
Command Type of the First LCR of a Row Change | Columns Required in the First LCR |
---|---|
|
The NEW column list must contain all non- |
|
The OLD column list must contain the key columns. The NEW column list must contain all updated scalar columns. All LOB, |
|
The OLD column list must contain the key columns. |
|
The NEW column list must contain the key columns and the modified LOB column. |
After constructing each LCR, you can call OCIXStreamInLCRSend()
to send that LCR. Then OCIXStreamInChunkSend()
can be called repeatedly to send the chunk data for each LOB or LONG
or XMLType
column in that LCR. Sending the chunk value for different columns cannot be interleaved. If a column contains multiple chunks, this function must be called consecutively using the same column name before proceeding to a new column. The ordering of the columns is irrelevant.
When invoking this function, you must pass OCI_XSTREAM_MORE_ROW_DATA
as the flag argument if there is more data for the current LCR. When sending the last chunk of the current LCR, this flag must be cleared to signal the end of the current LCR.
This function is valid only for INSERT
, UPDATE
, and LOB_WRITE
operations. Multiple LOB, LONG
, or XMLType
columns can be specified for INSERT
and UPDATE
, while only one LOB column is allowed for LOB_WRITE
operation.
Following is a sample client pseudocode snippet for non-callback mode (error checking is not included for simplicity):
main { /* Attach to inbound server */ OCIXStreamInAttach(); /* Get the server's processed low-position to determine * the position of the first LCR to generate. */ OCIXStreamInProcessedLWMGet(&lwm); while (TRUE) { flag = 0; /* construct lcr */ OCILCRHeaderSet(lcr); OCILCRRowColumnInfoSet(lcr); if (lcr has LOB | LONG | XMLType columns) set OCI_XSTREAM_MORE_ROW_DATA flag; status = OCIXStreamInLCRSend(lcr, flag); if (status == OCI_STILL_EXECUTING && (OCI_XSTREAM_MORE_ROW_DATA flag set)) { for each LOB/LONG/XMLType column in row change { for each chunk in column { /* set col_name, col_flag, chunk data */ construct chunk; if (last chunk of current column) col_flag |= OCI_LCR_COLUMN_LAST_CHUNK; if (last chunk of last column) clear OCI_XSTREAM_MORE_ROW_DATA flag; OCIXStreamInChunkSend(chunk, col_flag, flag); } } } else if (status == OCI_SUCCESS) { /* get lwm when SendLCR call ends successfully. */ OCIXStreamInProcessedLWMGet(&lwm); } if (some terminating_condition) break; } OCIXStreamInDetach(); }
Purpose
Attaches to an XStream outbound server.
Syntax
sword OCIXStreamOutAttach ( OCISvcCtx *svchp, OCIError *errhp, oratext *server_name, ub2 server_name_len, ub1 *last_position, ub2 last_position_len, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
XStream outbound server name.
Length of XStream outbound server name.
Position to the last received LCR. Can be NULL
.
Length of last_position
.
Specify OCI_DEFAULT
for now.
Comments
The OCIEnv
environment handle must be created with OCI_OBJECT
mode, and the service context must be in connected state to issue this function. This function does not support nonblocking mode. It returns either OCI_SUCCESS
or OCI_ERROR
status code.
The name of the outbound server must be provided because multiple outbound servers can be configured in one Oracle instance. This function returns OCI_ERROR
if it encounters any error while attaching to the outbound server. Only one client can attach to an XStream outbound server at any time. An error is returned if multiple clients attempt to attach to the same outbound server or if the same client attempts to attach to multiple outbound servers using the same service handle.
The last_position
parameter is used to establish the starting point of the stream. This call returns OCI_ERROR if the specified position is non-NULL
and less than the server's processed low-position (see "OCIXStreamOutProcessedLWMSet()"); otherwise, LCRs with positions greater than the specified last_position
will be sent to the user.
If the last_position
is NULL
then the stream will start from the processed low-position maintained in the server.
Purpose
Detaches from the outbound server.
Syntax
sword OCIXStreamOutDetach ( OCISvcCtx *svchp, OCIError *errhp, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Specify OCI_DEFAULT
for now.
Comments
This function sends the current local processed low-position to the server before detaching from the outbound server. The outbound server automatically restarts after this call. This function returns OCI_ERROR
if it is invoked while a OCIXStreamOutReceive()
call is in progress.
Purpose
Receives an LCR from an outbound stream. If there is an LCR available, this function immediately returns that LCR. The duration of each LCR is limited to the interval between two successive OCIXStreamOutLCRReceive()
calls. When there is no LCR available in the stream, this call returns a NULL
LCR after an idle timeout.
Syntax
sword OCIXStreamOutLCRReceive ( OCISvcCtx *svchp, OCIError *errhp, void **lcrp, ub1 *lcrtype, oraub8 *flag, ub1 *fetch_low_position, ub2 *fetch_low_position_len, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Pointer to the LCR received from the stream. If there is an available LCR, that LCR is returned with status code OCI_STILL_EXECUTING
. When the call ends, a NULL
LCR is returned with status code OCI_SUCCESS
.
Type of the retrieved LCR. This value is valid only when lcrp
is not NULL
.
Return flag. If bit OCI_XSTREAM_MORE_ROW_DATA
(0x01) is set, it means that this LCR has more data. You must use OCIXStreamOutReceiveChunk()
function to get the remaining data.
XStream outbound server's fetch low position. This value is returned only when the return code is OCI_SUCCESS
. Optional. If non-NULL
, then you must preallocate OCI_LCR_MAX_POSITION_LEN
bytes for the return value.
Length of fetch_low_position
.
Specify OCI_DEFAULT
for now.
Comments
To avoid network round trip for every OCIXStreamOutLCRReceive()
call, we will tie the connection to this call and let the server fill up the network buffer with LCRs so subsequent calls can quickly receive the LCRs from the network. The server will end each call at the transaction boundary after ACK interval elapses since the call began. When there is no LCR in the stream, the server will end the call after the idle timeout elapses.
Return codes:
OCI_STILL_EXECUTING
means that the current call is still in progress. The connection associated with the specified service context handle is still tied to this call for streaming the LCRs from the server. An error is returned if you attempt to use the same connection to execute any OCI calls that require database round trip, for example, OCIStmtExecute()
, OCIStmtFetch()
, OCILobRead()
, and so on. OCILCR*
calls do not require round trips; thus, they are valid while the call is in progress.
OCI_SUCCESS
means that the current call is completed. You are free to execute OCIStmt*
, OCILob*
, and so on, from the same service context
OCI_ERROR
means the current call encounters some errors. Use OCIErrorGet()
to obtain information about the error
This call always returns a NULL
LCR when the return code is OCI_SUCCESS
. In addition, it returns the fetch low position to denote that the outbound server has received all transactions with commit position lower than or equal to this value.
See Also:
"OCIXStreamOutChunkReceive()" for non-callback pseudocode in the Comments section
Purpose
Used to get the LCR stream from the outbound server using callbacks. You must supply a callback procedure to be invoked for each LCR received. If some LCRs in the stream may contain LOB
or LONG
or XMLType
columns, then a second callback must be supplied to process each chunk (see "OCIXStreamOutChunkReceive()").
Syntax
sword OCIXStreamOutLCRCallbackReceive ( OCISvcCtx *svchp, OCIError *errhp, OCICallbackXStreamOutLCRProcess processlcr_cb, OCICallbackXStreamOutChunkProcess processchunk_cb, void *usrctxp, ub1 *fetch_low_position, ub2 *fetch_low_position_len, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Callback function to process each LCR received by the client. Cannot be NULL
.
Callback function to process each chunk in the received LCR. Can be NULL
if you do not expect to receive any LCRs with additional chunk data.
User context to pass to both callback procedures.
XStream outbound server's fetch low position (see "OCIXStreamOutLCRReceive()"). Optional.
Length of fetch_low_position
.
Specify OCI_DEFAULT
for now.
Comments
Return code: OCI_SUCCESS
or OCI_ERROR
.
The processlcr_cb
argument must be of type OCICallbackXStreamOutLCRProcess
:
typedef sb4 (*OCICallbackXStreamOutLCRProcess) (void *usrctxp, void *lcrp, ub1 lcrtyp, oraub8 flag);
Parameters of OCICallbackXStreamOutLCRProcess()
Pointer to the user context.
Pointer to the LCR just received.
LCR type (OCI_LCR_XROW
or OCI_LCR_XDDL
).
If OCI_XSTREAM_MORE_ROW_DATA
is set, then the current LCR has more chunk data.
The input parameters of the processlcr_cb()
procedure are the user context, the LCR just received, its type, and a flag to indicate whether the LCR contains more data. If there is an LCR available, this callback is invoked immediately. If there is no LCR in the stream, after an idle timeout, this call will end with OCI_SUCCESS
return code. The valid return codes from OCICallbackXStreamOutLCRProcess()
callback function are OCI_CONTINUE
or OCI_SUCCESS
. This callback function must return OCI_CONTINUE
to continue processing OCIXStreamOutLCRCallbackReceive()
call. Any return code other than OCI_CONTINUE
signals that the client wants to terminate OCIXStreamOutLCRCallbackReceive()
immediately.
See Also:
"Server Handle Attributes"The processchunk_cb
argument must be of type OCICallbackXStreamOutChunkProcess
:
typedef sb4 (*OCICallbackXStreamOutChunkProcess) (void *usrctxp, oratext *column_name, ub2 column_name_len, ub2 column_dty, oraub8 column_flag, ub2 column_csid, ub4 chunk_bytes, ub1 *chunk_data, oraub8 flag );
Parameters of OCICallbackXStreamOutChunkProcess()
:
Pointer to the user context.
Column name of the current chunk.
Length of the column name.
Chunk data type (SQLT_CHR
or SQLT_BIN
).
See Comments in "OCIXStreamInChunkSend()".
Column character set id. Relevant only if the column is an XMLType
column (that is, column_flag
has OCI_LCR_COLUMN_XML_DATA
bit set).
Chunk data length in bytes.
Chunk data pointer.
If OCI_XSTREAM_MORE_ROW_DATA
is set, this means the current LCR has more chunk data.
The input parameters of the processchunk_cb()
procedure are the user context, the information about the chunk, and a flag. When the flag
argument has OCI_XSTREAM_MORE_ROW_DATA
(0x01) bit set, then it means there is more data for the current LCR. The valid return codes from OCICallbackXStreamOutChunkProcess()
callback function are OCI_CONTINUE
or OCI_SUCCESS
. This callback function must return OCI_CONTINUE
to continue processing OCIXStreamOutLCRCallbackReceive()
call. Any return code other than OCI_CONTINUE
signals that the client wants to terminate OCIXStreamOutLCRCallbackReceive()
immediately.
OCI calls are provided to access each field in the LCR. If the LCR contains only scalar column(s), the duration of that LCR is limited only to the processlcr_cb()
procedure. If the LCR contains some chunk data then the duration of the LCR is extended until all the chunks have been processed. If you want to access the LCR data at a later time, a copy of the LCR must be made before it is freed.
As for OCIXStreamOutLCRReceive()
, the server will end each call at the transaction boundary after each ACK interval since the call begins, or after each idle timeout. The default ACK interval is 30 seconds, and the default idle timeout is one second. See "Server Handle Attributes" to tune these values. This function also returns the fetch low position when the call ends.
The following figure shows the execution flow of the OCIXStreamOutLCRCallbackReceive()
function.
Figure 12-2 Execution Flow of the OCIXStreamOutLCRCallbackReceive() Function
* While OCI_XSTREAM_MORE_ROW_DATA
is set.
Description of the figure:
At 1, the client invokes OCIXStreamOutLCRCallbackReceive()
providing two callbacks. This function initiates an LCR outbound stream from the server.
At 2, this function receives an LCR from the stream and invokes processlcr_cb()
procedure with the LCR just received. It passes OCI_XSTREAM_MORE_ROW_DATA
flag to processlcr_cb()
if the current LCR has additional data.
If the current LCR has no additional chunk, then this function repeats 2 for the next LCR in the stream.
At 3, if the current LCR contains additional chunk data, then this function invokes processchunk_cb()
for each chunk received with OCI_XSTREAM_MORE_ROW_DATA
flag. This flag is cleared when the callback is invoked on the last chunk of the current LCR.
If there is more LCR in the stream, then it loops back to 2. This process continues until the end of the current call, or when there is no LCR in the stream for one second, or if a callback function returns any value other than OCI_CONTINUE
.
Here is sample pseudocode for callback mode:
main { /* Attach to outbound server specifying last position */ OCIXStreamOutAttach(last_pos); /* Update the local processed low-position */ OCIXStreamOutProcessedLWMSet(lwm); while (TRUE) { OCIXStreamOutLCRCallbackReceive(processlcr_cb, processchunk_cb, fwm); /* Use fetch low-position(fwm) * to update processed lwm if applied. */ /* Update the local lwm so it will be sent to * server during next call. */ OCIXStreamOutProcessedLWMSet(lwm); if (some terminating_condition) break; } OCIXStreamOutDetach(); } processlcr_cb (IN lcr, IN flag) { /* Process the LCR just received */ OCILCRHeaderGet(lcr); OCILCRRowColumnInfoGet(lcr); if (lcr is LOB_WRITE | LOB_TRIM | LOB_ERASE) OCILCRLobInfoGet(lcr); if (OCI_XSTREAM_MORE_ROW_DATA flag set) prepare_for_chunk_data; else process_end_of_row; } processchunk_cb (IN chunk, IN flag) { process_chunk; if (OCI_XSTREAM_MORE_ROW_DATA flag not set) process_end_of_row; }
Purpose
Updates the local copy of the processed low-position. It can be called anytime between OCIXStreamOutAttach()
and OCIXStreamOutDetach()
calls. Clients, using the callback mechanism to stream LCRs from the server (see "OCIXStreamOutLCRCallbackReceive()"), can invoke this function while in the callback procedures.
Syntax
sword OCIXStreamOutProcessedLWMSet ( OCISvcCtx *svchp, OCIError *errhp, ub1 *processed_low_position, ub2 processed_low_position_len, ub4 mode );
Parameters
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
The processed low position maintained at the client.
Length of processed_low_position
.
Specify OCI_DEFAULT
for now.
Comments
The processed low-position denotes all LCRs at or below it have been processed. After successfully attaching to an XStream outbound server, a local copy of the processed low-position is maintained at the client. Periodically, this position is sent to the server so that archived logs containing already processed transactions can be purged.
Return code: OCI_SUCCESS
or OCI_ERROR
.
Clients using XStreamOut
functions must keep track of the processed low-position based on what they have processed and call this function whenever their processed low-position has changed, so that a more current value is sent to the server during the next update, which occurs at the beginning of OCIXStreamOutLCRCallbackReceive()
and OCIXStreamDetach()
calls. For OCIXStreamOutLCRReceive()
call, the processed low-position is sent to the server when it initiates a request to start the outbound stream. It is not sent while the stream is in progress.
You can query DBA_XSTREAM_OUTBOUND_PROGRESS
view to confirm that the processed low-position has been saved in the server.
Purpose
Allows the client to retrieve the data of each LOB
or LONG
or XMLType
column one chunk at a time.
Syntax
sword OCIXStreamOutChunkReceive ( OCISvcCtx *svchp, OCIError *errhp, oratext **column_name, ub2 *column_name_len, ub2 *column_dty, oraub8 *column_flag, ub2 *column_csid, ub4 *chunk_bytes, ub1 **chunk_data, oraub8 *flag, ub4 mode );
Syntax
Service handle context.
An error handle you can pass to OCIErrorGet()
for diagnostic information in the event of an error.
Name of the column that has data.
Length of the column name.
Column chunk data type (either SQLT_CHR
or SQLT_BIN
).
Column flag. See Comments for valid flags.
Column character set id. This is returned only for XMLType
column, that is, column_flag
has OCI_LCR_COLUMN_XML_DATA
bit set.
Number of bytes in the returned chunk.
Pointer to the chunk data in the LCR. The client must not de-allocate this buffer since the LCR and its contents are maintained by this function
If OCI_XSTREAM_MORE_ROW_DATA
(0x01) is set, it means the current LCR has more chunks coming.
Specify OCI_DEFAULT
for now.
Comments
In Streams, LOB or LONG
or XMLType
column data is broken up into multiple LCRs based on how they are stored in the redo logs. Thus, for a row change containing these columns multiple LCRs may be constructed. The first LCR of a row change contains the column data for all the scalar columns. All LOB or LONG
or XMLType
columns in the first LCR are set to NULL
since their data are sent in subsequent LCRs for that row change. These column data are stored in the LCR as either RAW
(SQLT_BIN
) or VARCHAR2
(SQLT_CHR
) chunks as shown in the table Table 12-5:
Table 12-5 Storage of LOB or LONG Data in the LCR
Source Column Data Type | Streams LCR Data Type | Streams LCR Character Set |
---|---|---|
|
|
N/A |
Fixed-width |
|
Client Character Set |
Varying-width |
|
AL16UTF16 |
|
|
AL16UTF16 |
|
|
column |
In Streams, LOB, LONG
, or XMLType
column, data is broken up into multiple chunks based on how they are stored in the redo logs. For a row change containing columns of these data types, its associated LCR only contains data for the other scalar columns. All LOB, LONG
or XMLType
columns are either represented in the LCR as NULL
or not included in the LCR. The actual data for these columns are sent following each LCR as RAW
(SQLT_BIN
) or VARCHAR2
(SQLT_CHR
) chunks as shown in Table 12-5, "Storage of LOB or LONG Data in the LCR".
LCR column flags can be combined using the bitwise OR
operator.
#define OCI_LCR_COLUMN_LOB_DATA /* column contains LOB data */ #define OCI_LCR_COLUMN_LONG_DATA /* column contains long data */ #define OCI_LCR_COLUMN_EMPTY_LOB /* column has an empty LOB */ #define OCI_LCR_COLUMN_LAST_CHUNK /* last chunk of current column */ #define OCI_LCR_COLUMN_AL16UTF16 /* column is in AL16UTF16 fmt */ #define OCI_LCR_COLUMN_NCLOB /* column has NCLOB data */ #define OCI_LCR_COLUMN_XML_DATA /* column contains xml data */ #define OCI_LCR_COLUMN_XML_DIFF /* column contains xmldiff data */ #define OCI_LCR_COLUMN_ENCRYPTED /* column is encrypted */ #define OCI_LCR_COLUMN_UPDATED /* col is updated */
Return code: OCI_ERROR or OCI_SUCCESS.
This call returns a NULL
column name and NULL
chunk data if it is invoked when the current LCR does not contain LOB, LONG
, or XMLType
columns. This function is valid only when an OCIXStreamOutLCRReceive()
call is in progress. An error will be returned if it is called during other times.
If the return flag from OCIXStreamOutLCRReceive()
has OCI_XSTREAM_MORE_ROW_DATA
bit set, then you must iteratively call OCIXStreamOutChunkReceive()
to retrieve all the chunks belonging to that row change before getting the next row change (that is, before making the next OCIXStreamOutLCRReceive()
call); otherwise, an error will be returned.
Here is sample pseudocode for non-callback mode:
main { /* Attach to outbound server specifying last position */ OCIXStreamOutAttach(last_pos); /* Update the local processed low-position */ OCIXStreamOutProcessedLWMSet(lwm); while (TRUE) { status = OCIXStreamOutLCRReceive(lcr, flag, fwm); if (status == OCI_STILL_EXECUTING) { /* Process LCR just received */ OCILCRHeaderGet(lcr); OCILCRRowColumnInfoGet(lcr); while (OCI_XSTREAM_MORE_ROW_DATA flag set) { OCIXStreamReceiveChunk(chunk, flag, ); process_chunk; } process_end_of_row; } else if (status == OCI_SUCCESS) { /* Use fetch low-position(fwm) * to update processed lwm if applied. */ /* Update the local lwm so it will be sent to * server during next call. */ OCIXStreamOutProcessedLWMSet(lwm); if (some terminating_condition) break; } } OCIXStreamOutDetach(); }