如题,小弟初次接触不懂OCI,请大虾们帮忙改一下,下面两个函数#define YCJDDMAX_SQL_ITEMS 200
#define YCJDDMAX_SQL_VNAME_LEN 32
#define YCJDDMAX_SQL_INAME_LEN 32
#define YCJDDMAX_SQL_STRLEN 2048
#ifndef NULL
#define NULL 0
#endifextern SQLDA * sqlald();
extern void sqlnul();
EXEC SQL INCLUDE sqlca;
/*****************************************************************************/
/*                                                                           */
/*  函数名:CJDDDescribe                                                     */
/*                                                               */
/*  日  期:                                                    */
/*  接  口: 1. TCJDDConnection v_conn 数据库驱动连接标识               */
/* 2. const char * v_sqlstmt 欲分析的SQL语句                          */
/* 3. PTCJVSStruct v_out 结果集描述                                   */
/* 4. PTCJVSStruct v_in 输入变量描述                                 */
/* 5. PTCJHMHeap v_hp 内存堆结构指针                      */
/* 6. PTCJEMStack v_stack 错误堆栈指针,保存错误信息                   */
/*  返  回:int,成功或者失败。YCJOK:成功;YCJERROR:失败。                  */ 
/*  描  述:数据库驱动模块分析SQL语句的输入变量、输出结果              */
/*                                                                           */
/*                                                                           */
/*                                                               */
/*  日  期:                                                  */
/*  描  述:添加PTCJHMHeap参数,避免过多内存碎片                             */
/*                                                                           */
/*****************************************************************************/
int CJDDDescribe(TCJDDConnection v_conn, const char * v_sqlstmt, 
PTCJVSStruct v_out, PTCJVSStruct v_in,PTCJHMHeap v_hp,PTCJEMStack v_stack)
{
EXEC SQL CONTEXT USE :v_conn;
EXEC SQL BEGIN DECLARE SECTION;
char sql_statement[YCJDDMAX_SQL_STRLEN];
EXEC SQL END DECLARE SECTION;
/*struct sqlca sqlca;*/
int i;
SQLDA *bind_dp;
SQLDA *select_dp;
TCJVSVariable tcvb;
int null_ok;
int precision;
int scale;
int scale_col[YCJDDMAX_SQL_STRLEN];

/*alloc_descriptors*/
if ((bind_dp = sqlald(YCJDDMAX_SQL_ITEMS,YCJDDMAX_SQL_VNAME_LEN,
YCJDDMAX_SQL_INAME_LEN)) == (SQLDA *) 0)
{
CJEMPush(v_stack,5,1,'Z',"DDC",1,__LINE__,__FILE__,CJDDErrMsg[1]);
return YCJERROR; 
}

if ((select_dp = sqlald (YCJDDMAX_SQL_ITEMS,YCJDDMAX_SQL_VNAME_LEN,
YCJDDMAX_SQL_INAME_LEN)) == (SQLDA *) 0)
{
CJEMPush(v_stack,5,1,'Z',"DDC",2,__LINE__,__FILE__,CJDDErrMsg[2]);
return YCJERROR;
}
select_dp->N = YCJDDMAX_SQL_ITEMS;

/* Allocate the pointers to the indicator variables, and the
   actual data. */
for (i = 0; i < YCJDDMAX_SQL_ITEMS; i++) 
{
bind_dp->I[i] = (short *) CJHMAlloc(v_hp,sizeof (short),v_stack);
    select_dp->I[i] = (short *) CJHMAlloc(v_hp,sizeof(short),v_stack);
    bind_dp->V[i] = (char *)CJHMAlloc(v_hp,YCJDDMAX_SQL_VNAME_LEN,v_stack);
    select_dp->V[i]=(char *)CJHMAlloc(v_hp,YCJDDMAX_SQL_VNAME_LEN,v_stack);
    if(bind_dp->I[i]==NULL||select_dp->I[i]==NULL||bind_dp->V[i]==NULL||
     select_dp->V[i]==NULL)
     return YCJERROR;
}
strcpy(sql_statement,v_sqlstmt);
CJSTAllTrim(sql_statement);/*set_bind_variables*/
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL WHENEVER SQLWARNING CONTINUE;
    EXEC SQL WHENEVER SQLERROR GOTO lb_err;
EXEC SQL PREPARE S FROM :sql_statement;
EXEC SQL DECLARE C CURSOR FOR S;
    bind_dp->N = YCJDDMAX_SQL_ITEMS;  /* Initialize count of array elements. */
    EXEC SQL DESCRIBE BIND VARIABLES FOR S INTO bind_dp;     /* If F is negative, there were more bind variables
        than originally allocated by sqlald(). */
if (bind_dp->F < 0)
{
CJEMPush(v_stack,5,1,'Z',"DDC",3,__LINE__,__FILE__,CJDDErrMsg[3],
-bind_dp->F, YCJDDMAX_SQL_ITEMS);
return YCJERROR;
}
/* else if (bind_dp->F > 0)
{
CJEMPush(v_stack,5,1,'Z',"DDC",5,__LINE__,__FILE__,CJDDErrMsg[5]);
return YCJERROR;
}*/     /* Set the maximum number of array elements in the
     descriptor to the number found. */
bind_dp->N = bind_dp->F;
for (i = 0; i < bind_dp->F; i++)
{
bind_dp->L[i] = 4;
/* (re-)allocate the buffer for the value.
SQLSQLDAAlloc() reserves a pointer location for
V[i] but does not allocate the full space for
the pointer. */
if(CJHMFree(v_hp,bind_dp->V[i],v_stack)==YCJERROR)
return YCJERROR;
if((bind_dp->V[i]=(char *)CJHMAlloc(v_hp,5,v_stack))==NULL)
return YCJERROR;
/*bind_dp->V[i] = (char *) realloc(bind_dp->V[i],5);*/
/* And copy it in. */
strncpy(bind_dp->V[i], "NULL", 5);
*bind_dp->I[i] = -1;
/* Set the bind datatype to 1 for CHAR. */
bind_dp->T[i] = 1;

strncpy(tcvb.name,bind_dp->S[i],
YCJDDMAX_SQL_VNAME_LEN-1)[YCJDDMAX_SQL_VNAME_LEN-1]='\0';
CJSTRTrim(tcvb.name);
CJSTLTrim(tcvb.name);
tcvb.type=XCJVT_STRING;
tcvb.length=bind_dp->L[i]+1;
tcvb.precision=0;
tcvb.offset=0;
if(v_in!=NULL&&CJVSSAddField(v_in,tcvb.name,tcvb.type,tcvb.length,0,
v_stack)==YCJERROR)
{
CJEMPush(v_stack,5,1,'Z',"DDC",9,__LINE__,__FILE__,
CJDDErrMsg[9]);
return YCJERROR; 
}
}#ifdef YCJPLAT_WINDOWS
if (strncmpi(sql_statement, "SELECT", 6) != 0)
#else
if (strncasecmp(sql_statement, "SELECT", 6) != 0)
#endif
{
/* for(i=0;i<YCJDDMAX_SQL_ITEMS;i++)
{
if(bind_dp->V[i]!=(char *)NULL)
free(bind_dp->V[i]);
free(bind_dp->I[i]);
if(select_dp->V[i]!=(char *)NULL)
free(select_dp->V[i]);
free(select_dp->I[i]);
}*/
sqlclu(bind_dp);
sqlclu(select_dp);
return YCJOK;
}
EXEC SQL OPEN C USING DESCRIPTOR bind_dp;

解决方案 »

  1.   


    /*process_select_list*/ select_dp->N = YCJDDMAX_SQL_ITEMS;
    EXEC SQL DESCRIBE SELECT LIST FOR S INTO select_dp;
    if (select_dp->F < 0)
    {
    CJEMPush(v_stack,5,1,'Z',"DDC",4,__LINE__,__FILE__,
    CJDDErrMsg[4],-(select_dp->F), YCJDDMAX_SQL_ITEMS);
    return YCJERROR;
    }
    select_dp->N = select_dp->F;
    for (i = 0; i < select_dp->F; i++)
    {
    strncpy(tcvb.name,select_dp->S[i],
    YCJDDMAX_SQL_VNAME_LEN-1)[YCJDDMAX_SQL_VNAME_LEN-1]='\0';
    CJSTRTrim(tcvb.name);
    CJSTLTrim(tcvb.name);
         sqlnul ((unsigned short *)&(select_dp->T[i]), 
         (unsigned short *)&(select_dp->T[i]), &null_ok);

    switch (select_dp->T[i])
         {
             case  1 : /* CHAR datatype: no change in length
                         needed, except possibly for TO_CHAR
                         conversions (not handled here). */
                 break;
             case  2 : /* NUMBER datatype: use sqlprc() to
                         extract precision and scale. */
                 sqlprc ((unsigned long *)&(select_dp->L[i]), 
                 &precision, &scale);
                       /* Allow for maximum size of NUMBER. */

    scale_col[i]=scale;
    if (precision == 0) 
    {
    precision = 40;
    select_dp->L[i] = sizeof(TCJFLOAT8);
                    tcvb.type=XCJVT_DOUBLE;
                    select_dp->T[i] = 4;  /* float */
                }
                       /* Also allow for decimal point and
                          possible sign. */
                 /* convert NUMBER datatype to FLOAT if scale > 0,
                    INT otherwise. */
                else if (scale > 0)
    {
    select_dp->L[i] = sizeof(TCJFLOAT8);
                    tcvb.type=XCJVT_DOUBLE;
                    select_dp->T[i] = 4;  /* float */
    }
                else
                {
                 select_dp->T[i] = 3;  /* int */
                 if(precision>8)
                 select_dp->L[i] = sizeof(TCJINT8);
                 else
                 select_dp->L[i] = sizeof(TCJINT4);
                }
                break;

             case  8 : /* LONG datatype */
                 select_dp->L[i] = 240;
                 break;

             case 11 : /* ROWID datatype */
             case 104:
                 select_dp->L[i] = 18;
                 break;

             case 12 : /* DATE datatype 
                 select_dp->L[i] = 20;*/
                 break;

             case 23 : /* RAW datatype */
                 break;

             case 24 : /* LONG RAW datatype */
                 select_dp->L[i] = 240;
                 break;
         }
        /* Allocate space for the select-list data values.
           sqlald() reserves a pointer location for
           V[i] but does not allocate the full space for
           the pointer.  */
    if(CJHMFree(v_hp,select_dp->V[i],v_stack)==YCJERROR)
    return YCJERROR;
    if((select_dp->V[i]=(char *)CJHMAlloc(v_hp,select_dp->L[i],v_stack))
    ==NULL)
    return YCJERROR;
    /*select_dp->V[i] = (char *) realloc(select_dp->V[i],
                                    select_dp->L[i]); */  
        /* Print column headings, right-justifying number
            column headings. */     /* Coerce ALL datatypes except for LONG RAW and NUMBER to
           character. */
    if (select_dp->T[i] != 24 && select_dp->T[i] != 3&&
    select_dp->T[i] != 4 && select_dp->T[i] != 12)
             select_dp->T[i] = 1;
        /* Coerce the datatypes of NUMBERs to float or int depending on
           the scale. */
    /*if (select_dp->T[i] == 2)
    {
           if (scale > 0)
              select_dp->T[i] = 4;   float 
           else
              select_dp->T[i] = 3;   int 
              }*/ switch (select_dp->T[i])
    {
             case  1 : /* CHAR datatype: no change in length
                         needed, except possibly for TO_CHAR
                         conversions (not handled here). */
    tcvb.type=XCJVT_STRING;
    tcvb.length=select_dp->L[i]+1;
    break;
             case  3 :  /*long */
             if(precision>8)
             {
    tcvb.type=XCJVT_INT8;
    tcvb.length=sizeof(TCJINT8);
    }
    else
    {
    tcvb.type=XCJVT_INT4;
    tcvb.length=sizeof(TCJINT4);
    }
                 break;
         case 4 :  /* float */
    tcvb.type=XCJVT_DOUBLE;
    tcvb.length=select_dp->L[i];
    break;
    case 12 :  /* date */
    tcvb.type=XCJVT_DATETIME;
    tcvb.length=sizeof(CJDATETIME);
    break;
    default:
    break;
    }
    tcvb.precision=0;
    tcvb.offset=0;
    if(CJVSSAddField(v_out,tcvb.name,tcvb.type,tcvb.length,0,
    v_stack)==YCJERROR)
    {
    CJEMPush(v_stack,5,1,'Z',"DDC",9,__LINE__,__FILE__,
    CJDDErrMsg[9]);
    return YCJERROR; 
    }
    }
    /* FETCH each row selected and print the column values.
    *itemcount=select_dp->F; */
    /*clear*/
    /* for(i=0;i<YCJDDMAX_SQL_ITEMS;i++)
    {
    if(bind_dp->V[i]!=(char *)NULL)
    free(bind_dp->V[i]);
    free(bind_dp->I[i]);
    if(select_dp->V[i]!=(char *)NULL)
    free(select_dp->V[i]);
    free(select_dp->I[i]);
    }*/
    sqlclu(bind_dp);
    sqlclu(select_dp);
    EXEC SQL CLOSE C;
    return YCJOK;
    lb_err:
    /* for(i=0;i<YCJDDMAX_SQL_ITEMS;i++)
    {
    if(bind_dp->V[i]!=(char *)NULL)
    free(bind_dp->V[i]);
    free(bind_dp->I[i]);
    if(select_dp->V[i]!=(char *)NULL)
    free(select_dp->V[i]);
    free(select_dp->I[i]);
    }*/
    sqlclu(bind_dp);
    sqlclu(select_dp);
    CJDDOrasPushErr(&sqlca,__LINE__,v_stack);
    EXEC SQL WHENEVER SQLERROR CONTINUE;
    EXEC SQL CLOSE C;
    return YCJERROR;
    }