Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
Home -> Community -> Mailing Lists -> Oracle-L -> RE: Multithreaded Direct Path OCI Problems in Oracle 8i
I think we are hitting bug 1666360 which is fixed in 8.1.7.2. I missed it on my first metalink search.
Ian MacGregor
Stanford Linear Accelerator Center
ian_at_SLAC.Stanford.edu
-----Original Message-----
Sent: Tuesday, July 09, 2002 12:00 PM
To: Multiple recipients of list ORACLE-L
I have written before about our project to record channel archive data in Oracle. Channel archive data has to do with the status of the accelerator. We just started taking data on a klystron design which gloms together eight of the amplifiers to begin to meet the power needs for the Next Linear Collider.
We have a multi-threaded OCI direct path program which works quite well under Oracle 9i, but returns a 1403 error under Oracle 8i. The respective versions are 9.0.1.3 and 8.1.6.3. If we can get this program to work, it will be used at various high -energy physics labs around the world. One of the most interested labs is BESSY, Berliner Elektronenspeicherring-Geselschaft fur Synchrotronstralung mbH. They are not ready to implement 9i yet and want us to get it running against 8i. When I say us, I mean the developers. I've written lots of C programs, but none were multithreaded and nearly all were Pro*C.
There are two files involved the first sets up the environment.
#include "oci.h"
#include "oracle_defs.h"
#include "oci_defs.h"
/*
#ifdef DEBUG
*/
GLOBAL int db_init(char *instance,
ALL_OCI_HANDLES *all_oci_handles, ALL_OCI_HANDLES *thread_oci_handles){
int sts;
#ifdef DEBUG
fprintf(stderr, "instance = %s\n", instance);
#endif
memset(all_oci_handles, 0, sizeof(ALL_OCI_HANDLES));
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIInitialize((ub4) OCI_THREADED, (dvoid *) 0,
(dvoid * (*) (dvoid *, size_t)) 0, (dvoid * (*) (dvoid *, dvoid *, size_t)) 0, (void (*)(dvoid *, dvoid *)) 0 );if (sts != SUCCESS)
fprintf(stderr, "Error returned from OCIInitialize = %d\n", sts); return(ERROR);
sts = OCIInitialize((ub4) OCI_OBJECT, (dvoid *) 0,
(dvoid * (*) (dvoid *, size_t)) 0, (dvoid * (*) (dvoid *, dvoid *, size_t)) 0, (void (*)(dvoid *, dvoid *)) 0 );if (sts != SUCCESS)
fprintf(stderr, "Error returned from OCIInitialize = %d\n", sts); return(ERROR);
sts = OCIEnvInit( (OCIEnv **) &all_oci_handles->EnvH, OCI_DEFAULT,
(size_t) 0, (dvoid **) 0 );
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIEnvInit = %d\n", sts); return(ERROR);
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIEnvInit( (OCIEnv **) &thread_oci_handles->EnvH, OCI_DEFAULT,
(size_t) 0, (dvoid **) 0 );
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIEnvInit = %d\n", sts); return(ERROR);
sts = OCIHandleAlloc( (dvoid *) all_oci_handles->EnvH, (dvoid **) &all_oci_handles->ErrH,
OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #1 = %d\n", sts); return(ERROR);
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIHandleAlloc( (dvoid *) thread_oci_handles->EnvH, (dvoid **) &thread_oci_handles->ErrH,
OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #1 = %d\n", sts); return(ERROR);
/* Server contexts.
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIHandleAlloc( (dvoid *) thread_oci_handles->EnvH, (dvoid **) &thread_oci_handles->SrvH,
OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #2 = %d\n", sts); return(ERROR);
sts = OCIHandleAlloc( (dvoid *) all_oci_handles->EnvH, (dvoid **) &all_oci_handles->SvcH,
OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #3 = %d\n", sts); return(ERROR);
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIHandleAlloc( (dvoid *) thread_oci_handles->EnvH, (dvoid **) &thread_oci_handles->SvcH,
OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #3 = %d\n", sts); return(ERROR);
sts = OCIServerAttach(all_oci_handles->SrvH, all_oci_handles->ErrH, (text *)instance,
strlen(instance), 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIServerAttach = %d\n", sts); return(ERROR);
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIServerAttach(thread_oci_handles->SrvH, thread_oci_handles->ErrH, (text *)instance,
strlen(instance), 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIServerAttach = %d\n", sts); return(ERROR);
/* Set attribute context in the service context.
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIAttrSet( (dvoid *) thread_oci_handles->SvcH, OCI_HTYPE_SVCCTX,
(dvoid *) thread_oci_handles->SrvH, (ub4) 0, OCI_ATTR_SERVER, (OCIError *) thread_oci_handles->ErrH);if (sts != SUCCESS)
fprintf(stderr, "Error returned from OCIAttrSet = %d\n", sts); return(ERROR);
sts = OCIHandleAlloc((dvoid *) all_oci_handles->EnvH, (dvoid **) &all_oci_handles->SesH,
(ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0);
fprintf(stderr, "Error returned from OCIHandleAlloc #4 = %d\n", sts); return(ERROR);
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIHandleAlloc((dvoid *) thread_oci_handles->EnvH, (dvoid **) &thread_oci_handles->SesH,
(ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0);
fprintf(stderr, "Error returned from OCIHandleAlloc #4 = %d\n", sts); return(ERROR);
sts = OCIHandleAlloc((dvoid *) all_oci_handles->EnvH, (dvoid **) &all_oci_handles->SelectStmt,
(ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #5 = %d\n", sts); return(ERROR);
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIHandleAlloc((dvoid *) thread_oci_handles->EnvH, (dvoid **) &thread_oci_handles->SelectStmt,
(ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #5 = %d\n", sts); return(ERROR);
sts = OCIHandleAlloc((dvoid *) all_oci_handles->EnvH, (dvoid **) &all_oci_handles->InsertStmt,
(ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #6 = %d\n", sts); return(ERROR);
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIHandleAlloc((dvoid *) thread_oci_handles->EnvH, (dvoid **) &thread_oci_handles->InsertStmt,
(ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #6 = %d\n", sts); return(ERROR);
sts = OCIHandleAlloc((dvoid *) all_oci_handles->EnvH, (dvoid **) &all_oci_handles->UpdateStmt,
(ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #6 = %d\n", sts); return(ERROR);
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIHandleAlloc((dvoid *) thread_oci_handles->EnvH, (dvoid **) &thread_oci_handles->UpdateStmt,
(ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
if (sts != SUCCESS)
{
fprintf(stderr, "Error returned from OCIHandleAlloc #6 = %d\n", sts); return(ERROR);
return(SUCCESS);
}
#include "oci.h"
#include "oracle_defs.h"
#include "oci_defs.h"
GLOBAL int float_table_init(ALL_OCI_HANDLES *all_oci_handles,
int direct_path_buf_rows){
int sts;
int i;
int pos;
int stat;
char float_table_name[] = "arch_data_f"; char float_table_schema_name[] = "";
char float_table_col_names[FLOAT_TABLE_NCOL_TBL][MAX_NAME_COL_LEN + 1] =
{"pv_id", "value", "timestamp", "nanosecs", "stat", "sevr", "ostat"}; int float_table_col_exttyp[FLOAT_TABLE_NCOL_TBL] = {SQLT_INT, SQLT_FLT, SQLT_DAT, SQLT_INT, SQLT_INT, SQLT_INT, SQLT_INT}; int float_table_maxlen_fld[FLOAT_TABLE_NCOL_TBL] = {38, 15, 7, 9, 8, 8, 16}; int float_table_precision[FLOAT_TABLE_NCOL_TBL] = {38, 15, 0, 9, 8, 8, 16}; int float_table_scale[FLOAT_TABLE_NCOL_TBL] = {0, 5, 0, 0, 0, 0, 0};
TABLE_INFO float_table_info;
COL_INFO *colp;
FLD_INFO *fldp;
OCIParam *colDesc;
ub2 num_cols;
ub2 exttyp_col;
ub2 csid_col;
ub1 prec_col;
sb1 scale_col;
ub4 maxlen_fld;
ub4 buf_size = 300000;
ub4 num_rows;
text Error[512];
sb4 ErrorCode;
/***Logic begins */
num_rows = direct_path_buf_rows;
/* Step 1 (performing the OCI initialization) has been done previously.
Step 2 is to allocate a direct path context handle and set the attributes. ------------------------------------------------------------------------ */ sts = OCIHandleAlloc((dvoid *) all_oci_handles->EnvH, (dvoid **) &all_oci_handles->FloatTableDirPathCtxH, (ub4) OCI_HTYPE_DIRPATH_CTX, (size_t) 0, (dvoid **) 0);if (sts != SUCCESS)
fprintf(stderr, "Error returned from OCIHandleAlloc #1 = %d\n", sts); OCIErrorGet(all_oci_handles->ErrH, (ub4) 1, (text *) NULL, &ErrorCode, Error, (ub4) sizeof(Error), OCI_HTYPE_ERROR); fprintf(stderr, "Error: %s\n", Error); return(ERROR);
sts = OCIAttrSet((dvoid *) all_oci_handles->FloatTableDirPathCtxH, (ub4) OCI_HTYPE_DIRPATH_CTX, (dvoid *) &buf_size, (ub4) 0, (ub4) OCI_ATTR_BUF_SIZE, all_oci_handles->ErrH);if (sts != SUCCESS)
fprintf(stderr, "Error returned from OCIAttrSet #1 = %d\n", sts); return(ERROR);
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIAttrSet((dvoid *) all_oci_handles->FloatTableDirPathCtxH, (ub4) OCI_HTYPE_DIRPATH_CTX, (dvoid *) &num_rows, (ub4) 0, (ub4) OCI_ATTR_NUM_ROWS, all_oci_handles->ErrH);if (sts != SUCCESS)
fprintf(stderr, "Error returned from OCIAttrSet #2 = %d\n", sts); OCIErrorGet(all_oci_handles->ErrH, (ub4) 1, (text *) NULL, &ErrorCode, Error, (ub4) sizeof(Error), OCI_HTYPE_ERROR); fprintf(stderr, "Error: %s\n", Error); return(ERROR);
/* Fill in the float_table_info data structure, which describes the
table to be loaded using the direct path API. This data structure includes information about each column of the table. --------------------------------------------------------------------- */strcpy(float_table_info.name_tbl, float_table_name);
float_table_info.ncol_tbl = FLOAT_TABLE_NCOL_TBL;
float_table_info.col_tbl = (COL_INFO *) malloc(FLOAT_TABLE_NCOL_TBL *
sizeof(COL_INFO));
if (float_table_info.col_tbl == NULL)
{
fprintf(stderr, "Unable to allocate float_table_info.col_tbl\n"); return(ERROR);
float_table_info.fld_tbl = (FLD_INFO *) malloc(FLOAT_TABLE_NCOL_TBL *
sizeof(FLD_INFO));
if (float_table_info.fld_tbl == NULL)
{
fprintf(stderr, "Unable to allocate float_table_info.fld_tbl\n"); return(ERROR);
for (i = 0, colp = float_table_info.col_tbl, fldp = float_table_info.fld_tbl;
i < FLOAT_TABLE_NCOL_TBL; i++, colp++, fldp++) {
colp->id_col = 0; strcpy(colp->name_col, float_table_col_names[i]); colp->exttyp_col = float_table_col_exttyp[i]; strcpy(colp->datemask_col, ""); colp->prec_col = float_table_precision[i]; colp->scale_col = float_table_scale[i]; colp->csid_col = 0; fldp->maxlen_fld = float_table_maxlen_fld[i];}
/* Step 3 is to supply the name of the object (in this case, the
name of a table) to be loaded.
#ifdef ORACLE_9I_OR_HIGHER
sts = OCIAttrSet((dvoid *) all_oci_handles->FloatTableDirPathCtxH, (ub4) OCI_HTYPE_DIRPATH_CTX, (dvoid *) float_table_schema_name, (ub4) strlen((const char *) float_table_schema_name), (ub4) OCI_ATTR_SCHEMA_NAME, all_oci_handles->ErrH);if (sts != SUCCESS)
fprintf(stderr, "Error returned from OCIAttrSet #4 = %d\n", sts); return(ERROR);
/* Step 4 is to describe the external data types of the table columns.
sts = OCIAttrGet((dvoid *) all_oci_handles->FloatTableDirPathCtxH, OCI_HTYPE_DIRPATH_CTX, (dvoid *) &all_oci_handles->FloatTableColLstDesc, (ub4 *) 0, OCI_ATTR_LIST_COLUMNS, all_oci_handles->ErrH);if (sts != SUCCESS)
fprintf(stderr, "Error returned from OCIAttrGet #1 = %d\n", sts); return(ERROR);
for (i = 0, pos = 1, colp = float_table_info.col_tbl, fldp = float_table_info.fld_tbl;
i < FLOAT_TABLE_NCOL_TBL; i++, pos++, colp++, fldp++) {
sts = OCIParamGet((dvoid *) all_oci_handles->FloatTableColLstDesc, (ub4) OCI_DTYPE_PARAM, (dvoid *) all_oci_handles->ErrH, (dvoid **) &colDesc, pos); if (sts != SUCCESS) { fprintf(stderr, "Error returned from OCIParamGet = %d\n", sts); return(ERROR); } colp->id_col = i; sts = OCIAttrSet((dvoid *) colDesc, (ub4) OCI_DTYPE_PARAM, (dvoid *) colp->name_col, (ub4) strlen((const char *)colp->name_col), (ub4) OCI_ATTR_NAME, all_oci_handles->ErrH); if (sts != SUCCESS) { fprintf(stderr, "Error returned from OCIAttrSet #6 = %d\n", sts); return(ERROR); } exttyp_col = (ub2) colp->exttyp_col; sts = OCIAttrSet((dvoid *) colDesc, (ub4) OCI_DTYPE_PARAM, (dvoid *) &exttyp_col, (ub4) 0, (ub4) OCI_ATTR_DATA_TYPE, all_oci_handles->ErrH); if (sts != SUCCESS) { fprintf(stderr, "Error returned from OCIAttrSet #7 = %d\n", sts); return(ERROR); } maxlen_fld = (ub4) fldp->maxlen_fld; sts = OCIAttrSet((dvoid *) colDesc, (ub4) OCI_DTYPE_PARAM, (dvoid *) &maxlen_fld, (ub4) 0, (ub4) OCI_ATTR_DATA_SIZE, all_oci_handles->ErrH); if (sts != SUCCESS) { fprintf(stderr, "Error returned from OCIAttrSet #8 = %d\n", sts); return(ERROR); } if (strlen(colp->datemask_col) > 0) { sts = OCIAttrSet((dvoid *) colDesc, (ub4) OCI_DTYPE_PARAM, (dvoid *) colp->datemask_col, (ub4) strlen((const char *) colp->datemask_col), (ub4) OCI_ATTR_DATEFORMAT, all_oci_handles->ErrH); if (sts != SUCCESS) { fprintf(stderr, "Error returned from OCIAttrSet #9 = %d\n", sts); return(ERROR); } } if (colp->prec_col) { prec_col = (ub1) colp->prec_col; sts = OCIAttrSet((dvoid *) colDesc, (ub4) OCI_DTYPE_PARAM, (dvoid *) &prec_col, (ub4) 0, (ub4) OCI_ATTR_PRECISION, all_oci_handles->ErrH); if (sts != SUCCESS) { fprintf(stderr, "Error returned from OCIAttrSet #10 = %d\n", sts); return(ERROR); } } if (colp->scale_col) { scale_col = (sb1) colp->scale_col; sts = OCIAttrSet((dvoid *) colDesc, (ub4) OCI_DTYPE_PARAM, (dvoid *) &scale_col, (ub4) 0, (ub4) OCI_ATTR_SCALE, all_oci_handles->ErrH); if (sts != SUCCESS) { fprintf(stderr, "Error returned from OCIAttrSet #11 = %d\n", sts); return(ERROR); } } if (colp->csid_col) { csid_col = (ub2) colp->csid_col; sts = OCIAttrSet((dvoid *) colDesc, (ub4) OCI_DTYPE_PARAM, (dvoid *) &csid_col, (ub4) 0, (ub4) OCI_ATTR_CHARSET_ID, all_oci_handles->ErrH); if (sts != SUCCESS) { fprintf(stderr, "Error returned from OCIAttrSet #12 = %d\n", sts); return(ERROR); } } sts = OCIDescriptorFree((dvoid *) colDesc, OCI_DTYPE_PARAM); if (sts != SUCCESS) { fprintf(stderr, "Error returned from OCIDescriptorFree = %d\n", sts); return(ERROR); }
}
free(float_table_info.col_tbl);
free(float_table_info.fld_tbl);
#ifdef ORACLE_9I_OR_HIGHER
sts = lock_table(all_oci_handles, float_table_name);
if (sts != SUCCESS)
{
fprintf(stderr, "error return from lock_table\n"); return(sts);
/* Step 5 is to prepare the direct path interface.
/***TESTING return(ERROR); */ exit(0);
sts = commit_trans(all_oci_handles);
if (sts != SUCCESS)
{
fprintf(stderr, "error return from commit_trans\n"); return(sts);
/* Step 6 is to allocate a column array.
/* Step 7 is to allocate a direct path stream.
/* Get the number of rows and columns in the column array just allocated.
sts = OCIAttrGet(all_oci_handles->FloatTableColArrayH, (ub4) OCI_HTYPE_DIRPATH_COLUMN_ARRAY,
&all_oci_handles->FloatTableNumCols, 0, OCI_ATTR_NUM_COLS, all_oci_handles->ErrH);if (sts != SUCCESS)
fprintf(stderr, "Error returned from OCIAttrGet #3 = %d\n", sts); return(ERROR);
#ifdef DEBUG
fprintf(stderr, "FloatTableNumRows = %d\n", all_oci_handles->FloatTableNumRows);
fprintf(stderr, "FloatTableNumCols = %d\n", all_oci_handles->FloatTableNumCols);
#endif
return(SUCCESS);
}
Ian MacGregor
Stanford Linear Accelerator Center
ian_at_SLAC
-- Please see the official ORACLE-L FAQ: http://www.orafaq.com -- Author: MacGregor, Ian A. INET: ian_at_SLAC.Stanford.EDU Fat City Network Services -- (858) 538-5051 FAX: (858) 538-5051 San Diego, California -- Public Internet access / Mailing Lists -------------------------------------------------------------------- To REMOVE yourself from this mailing list, send an E-Mail message to: ListGuru_at_fatcity.com (note EXACT spelling of 'ListGuru') and in the message BODY, include a line containing: UNSUB ORACLE-L (or the name of mailing list you want to be removed from). You may also send the HELP command for other information (like subscribing). -- Please see the official ORACLE-L FAQ: http://www.orafaq.com -- Author: MacGregor, Ian A. INET: ian_at_SLAC.Stanford.EDU Fat City Network Services -- (858) 538-5051 FAX: (858) 538-5051 San Diego, California -- Public Internet access / Mailing Lists -------------------------------------------------------------------- To REMOVE yourself from this mailing list, send an E-Mail message to: ListGuru_at_fatcity.com (note EXACT spelling of 'ListGuru') and in the message BODY, include a line containing: UNSUB ORACLE-L (or the name of mailing list you want to be removed from). You may also send the HELP command for other information (like subscribing).Received on Tue Jul 09 2002 - 15:47:21 CDT