OCILIB (C Driver for Oracle) 3.12.1
statement.c
00001 /*
00002     +-----------------------------------------------------------------------------------------+
00003     |                                                                                         |
00004     |                               OCILIB - C Driver for Oracle                              |
00005     |                                                                                         |
00006     |                                (C Wrapper for Oracle OCI)                               |
00007     |                                                                                         |
00008     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2013 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: statement.c, Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_BindFreeAll
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 boolean OCI_BindFreeAll
00046 (
00047     OCI_Statement *stmt
00048 )
00049 {
00050     int i;
00051 
00052     OCI_CHECK(stmt == NULL, FALSE);
00053 
00054     /* free user binds */
00055 
00056     if (stmt->ubinds != NULL)
00057     {
00058         for(i = 0; i < stmt->nb_ubinds; i++)
00059         {
00060             OCI_BindFree(stmt->ubinds[i]);
00061         }
00062 
00063         OCI_FREE(stmt->ubinds);
00064     }
00065 
00066     /* free register binds */
00067 
00068     if (stmt->rbinds != NULL)
00069     {
00070         for(i = 0; i < stmt->nb_rbinds; i++)
00071         {
00072             OCI_BindFree(stmt->rbinds[i]);
00073         }
00074 
00075         OCI_FREE(stmt->rbinds);
00076     }
00077 
00078     stmt->nb_ubinds = 0;
00079     stmt->nb_rbinds = 0;
00080 
00081     return TRUE;
00082 }
00083 
00084 /* --------------------------------------------------------------------------------------------- *
00085  * OCI_BindCheck
00086  * --------------------------------------------------------------------------------------------- */
00087 
00088 boolean OCI_BindCheck
00089 (
00090     OCI_Statement *stmt
00091 )
00092 {
00093     boolean res   = TRUE;
00094     OCI_Bind *bnd = NULL;
00095     sb2 *ind      = NULL;
00096     ub4 i, j;
00097 
00098     OCI_CHECK(stmt == NULL, FALSE)
00099     OCI_CHECK(stmt->ubinds == NULL, TRUE);
00100 
00101     for(i = 0; i < stmt->nb_ubinds; i++)
00102     {
00103         bnd = stmt->ubinds[i];
00104         ind = (sb2 *) bnd->buf.inds;
00105 
00106         if (bnd->type == OCI_CDT_CURSOR)
00107         {
00108             OCI_Statement *bnd_stmt = (OCI_Statement *) bnd->buf.data;
00109 
00110             OCI_StatementReset(bnd_stmt);
00111 
00112             bnd_stmt->hstate = OCI_OBJECT_ALLOCATED_BIND_STMT;
00113         
00114             /* allocate stmt handle */
00115 
00116             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) bnd_stmt->con->env,
00117                                                   (dvoid **) (void *) &bnd_stmt->stmt,
00118                                                   (ub4) OCI_HTYPE_STMT,
00119                                                   (size_t) 0, (dvoid **) NULL));
00120 
00121             if (res == TRUE)
00122             {
00123                 ub4 size = 0;
00124 
00125                 size = bnd_stmt->prefetch_size ? bnd_stmt->prefetch_size : OCI_PREFETCH_SIZE;
00126                 res  = (res && OCI_SetPrefetchSize(bnd_stmt, size));
00127                 
00128                 size = bnd_stmt->fetch_size ? bnd_stmt->fetch_size : OCI_FETCH_SIZE;
00129                 res  = (res && OCI_SetFetchSize(bnd_stmt, size));
00130             }
00131         }
00132 
00133         if (bnd->direction & OCI_BDM_IN)
00134         {
00135             /* for strings, re-initialize length array with buffer default size */
00136 
00137             if (bnd->type == OCI_CDT_TEXT)
00138             {
00139                 for (j=0; j < bnd->buf.count; j++)
00140                 {
00141                     *(ub2*)(((ub1 *)bnd->buf.lens) + (sizeof(ub2) * (size_t) j)) = (ub2) bnd->size;
00142                 }
00143             }
00144 
00145             /* extra work for internal allocated binds buffers */
00146 
00147             if (bnd->is_array == FALSE)
00148             {
00149                 /* - For big integer (64 bits), we use an OCINumber.
00150 
00151                    - Oracle date/time type is the only non scalar type
00152                      implemented by oracle through a public structure instead
00153                      of using a handle. So we need to copy the value
00154                 */
00155 
00156                 if ((bnd->type == OCI_CDT_NUMERIC) && (bnd->code == SQLT_VNU))
00157                 {
00158                     res = OCI_NumberSet(stmt->con,  (OCINumber *) bnd->buf.data,
00159                                         (uword) sizeof(big_int), bnd->subtype, bnd->code, 
00160                                         (void *) bnd->input);
00161                 }
00162                 else if (bnd->alloc == TRUE)
00163                 {
00164                     if (bnd->type == OCI_CDT_DATETIME)
00165                     {
00166                         if (bnd->input != NULL)
00167                         {
00168                             memcpy((void *) bnd->buf.data,
00169                                    ((OCI_Date *) bnd->input)->handle, sizeof(OCIDate));
00170                         }
00171                     }
00172 
00173                 #ifdef OCI_CHECK_DATASTRINGS
00174 
00175                     else if (bnd->type == OCI_CDT_TEXT)
00176                     {
00177                         /* need conversion if bind buffer was allocated */
00178 
00179                         int osize = -1;
00180 
00181                         OCI_GetOutputString(bnd->input, bnd->buf.data, &osize,
00182                                             sizeof(dtext), sizeof(odtext));
00183                     }
00184 
00185                 #endif
00186 
00187                     else
00188                     {
00189                         if (bnd->input != NULL)
00190                         {
00191                             bnd->buf.data[0] = ((OCI_Datatype *) bnd->input)->handle;
00192                         }
00193                     }
00194                 }
00195 
00196                 /* for handles, check anyway the value for null data */
00197 
00198                 if ((bnd->type != OCI_CDT_NUMERIC) &&
00199                     (bnd->type != OCI_CDT_TEXT   ) &&
00200                     (bnd->type != OCI_CDT_RAW    ))
00201                 {
00202                     if (ind != NULL && *ind != -1)
00203                     {
00204                         *ind = OCI_IND(bnd->buf.data);
00205                     }
00206                 }
00207 
00208                 /* update bind object indicator pointer with object indicator */
00209 
00210                 if (bnd->type == OCI_CDT_OBJECT)
00211                 {
00212                     bnd->buf.obj_inds[0] = ((OCI_Object *) bnd->input)->tab_ind;
00213                 }
00214 
00215                 if (res == FALSE)
00216                 {
00217                     break;
00218                 }
00219             }
00220             else
00221             {
00222                 for (j = 0; j < bnd->buf.count; j++, ind++)
00223                 {
00224 
00225                     /* - For big integer (64 bits), we use an OCINumber.
00226 
00227                        - Oracle date/time type is the only non scalar type
00228                          implemented by oracle through a public structure instead
00229                          of using a handle. So we need to copy the value
00230                     */
00231 
00232                     if ((bnd->type == OCI_CDT_NUMERIC) && (bnd->code == SQLT_VNU))
00233                     {
00234 
00235                         res = OCI_NumberSet(stmt->con,
00236                                             (OCINumber *) ((ub1 *) bnd->buf.data +
00237                                             (size_t) (j*bnd->size)),
00238                                             (uword) sizeof(big_int), bnd->subtype, bnd->code,
00239                                             (void *) (((ub1 *) bnd->input) +
00240                                             (((size_t)j)*sizeof(big_int))));
00241                     }
00242                     else if (bnd->alloc == TRUE)
00243                     {
00244                         if (bnd->type == OCI_CDT_DATETIME)
00245                         {
00246                             if (bnd->input[j] != NULL)
00247                             {
00248                                 memcpy(((ub1 *) bnd->buf.data) + (size_t) (j*bnd->size),
00249                                        ((OCI_Date *) bnd->input[j])->handle, sizeof(OCIDate));
00250                             }
00251                         }
00252 
00253                     #ifdef OCI_CHECK_DATASTRINGS
00254 
00255                         else if (bnd->type == OCI_CDT_TEXT)
00256                         {
00257                             /* need conversion if bind buffer was allocated */
00258 
00259                             int osize   = -1;
00260                             int offset1 = (bnd->size/sizeof(odtext))*sizeof(dtext);
00261                             int offset2 = bnd->size;
00262 
00263                             OCI_GetOutputString(((ub1 *) bnd->input)    + (j*offset1),
00264                                                 ((ub1 *) bnd->buf.data) + (j*offset2),
00265                                                 &osize, sizeof(dtext), sizeof(odtext));
00266 
00267                             /* set zero terminal null character */
00268 
00269                             {
00270                                 odtext *str = (odtext *) (((ub1 *) bnd->buf.data) + (j*offset2));
00271 
00272                                 if (osize> 0)
00273                                 {
00274                                     str[osize/sizeof(odtext)] = 0;
00275                                 }
00276                                 else
00277                                 {
00278                                     str[0] = 0;
00279                                 }
00280                             }
00281                         }
00282 
00283                     #endif
00284 
00285                         else
00286                         {
00287                             if (bnd->input[j] != NULL)
00288                             {
00289                                 bnd->buf.data[j] = ((OCI_Datatype *) bnd->input[j])->handle;
00290                             }
00291                         }
00292                     }
00293 
00294                     /* for handles, check anyway the value for null data */
00295 
00296                     if ((bnd->type != OCI_CDT_NUMERIC) &&
00297                         (bnd->type != OCI_CDT_TEXT   ) &&
00298                         (bnd->type != OCI_CDT_RAW    ))
00299                     {
00300                         if (ind != NULL && *ind != -1)
00301                         {
00302                             *ind = OCI_IND((((OCI_Datatype *) bnd->input[j])->handle));
00303                         }
00304                     }
00305 
00306                     /* update bind object indicator pointer with object indicator */
00307 
00308                     if (bnd->type == OCI_CDT_OBJECT)
00309                     {
00310                         bnd->buf.obj_inds[j] = ((OCI_Object *) bnd->input[j])->tab_ind;
00311                     }
00312 
00313                     if (res == FALSE)
00314                     {
00315                         break;
00316                     }
00317                 }
00318             }
00319         }
00320     }
00321 
00322     return res;
00323 }
00324 
00325 /* --------------------------------------------------------------------------------------------- *
00326  * OCI_BindReset
00327  * --------------------------------------------------------------------------------------------- */
00328 
00329 boolean OCI_BindReset
00330 (
00331     OCI_Statement *stmt
00332 )
00333 {
00334     ub4 i, j;
00335     boolean res = TRUE;
00336 
00337     OCI_CHECK(stmt == NULL, FALSE)
00338     OCI_CHECK(stmt->ubinds == NULL, FALSE);
00339 
00340     /* avoid unused param warning from compiler */
00341 
00342     i = j = 0;
00343 
00344     for(i = 0; i < stmt->nb_ubinds; i++)
00345     {
00346         OCI_Bind *bnd = stmt->ubinds[i];
00347 
00348         if (bnd->type == OCI_CDT_CURSOR)
00349         {
00350             OCI_Statement *bnd_stmt = (OCI_Statement *) bnd->buf.data;
00351 
00352             bnd_stmt->status = OCI_STMT_PREPARED  | OCI_STMT_PARSED | 
00353                                OCI_STMT_DESCRIBED | OCI_STMT_EXECUTED;
00354 
00355             bnd_stmt->type   = OCI_CST_SELECT;
00356         }
00357 
00358         if ((bnd->direction & OCI_BDM_OUT) && (bnd->input != NULL) && (bnd->buf.data != NULL))
00359         {
00360             /* only reset bind indicators if bind was not a PL/SQL bind
00361                that can have oupout values
00362             */
00363 
00364             if (stmt->type != OCI_CST_BEGIN && stmt->type != OCI_CST_DECLARE)
00365             {
00366                 memset(bnd->buf.inds, 0, ((size_t) bnd->buf.count) * sizeof(sb2));
00367             }
00368             else
00369             {
00370                 /* extra work for internal allocated binds buffers with PL/SQL */
00371 
00372                 if (bnd->is_array == FALSE)
00373                 {
00374                     /* - For big integer (64 bits), we use an OCINumber.
00375 
00376                        - Oracle date/time type is the only non scalar type
00377                          implemented by oracle through a public structure instead
00378                          of using a handle. So we need to copy the value
00379                     */
00380 
00381                     if ((bnd->type == OCI_CDT_NUMERIC) && (bnd->code == SQLT_VNU))
00382                     {
00383                         res = OCI_NumberGet(stmt->con, (OCINumber *) bnd->buf.data,
00384                                             (uword) sizeof(big_int), bnd->subtype, bnd->code,
00385                                             (void *) bnd->input);
00386                     }
00387                     else if (bnd->alloc == TRUE)
00388                     {
00389 
00390                         if (bnd->type == OCI_CDT_DATETIME)
00391                         {
00392                             if (bnd->input != NULL)
00393                             {
00394                                 memcpy(((OCI_Date *) bnd->input)->handle,
00395                                        (void *) bnd->buf.data, sizeof(OCIDate));
00396                             }
00397                         }
00398 
00399                         /* update object indicator with bind object indicator
00400                          *pointer */
00401 
00402                         if (bnd->type == OCI_CDT_OBJECT)
00403                         {
00404                             if (bnd->input != NULL)
00405                             {
00406                                 ((OCI_Object *) bnd->input)->tab_ind = bnd->buf.obj_inds[0];
00407                             }
00408                         }
00409                     }
00410                 }
00411                 else
00412                 {
00413                     for (j = 0; j < bnd->buf.count; j++)
00414                     {
00415 
00416                         /* - For big integer (64 bits), we use an OCINumber.
00417 
00418                            - Oracle date/time type is the only non scalar type
00419                              implemented by oracle through a public structure instead
00420                              of using a handle. So we need to copy the value
00421                         */
00422 
00423                         if ((bnd->type == OCI_CDT_NUMERIC) && (bnd->code == SQLT_VNU))
00424                         {
00425 
00426                             res = OCI_NumberGet(stmt->con,
00427                                                 (OCINumber *) ((ub1 *) bnd->buf.data +
00428                                                 (size_t) (j*bnd->size)),
00429                                                 (uword) sizeof(big_int), bnd->subtype, bnd->code,
00430                                                 (void *) (((ub1 *) bnd->input) +
00431                                                 (((size_t)j)*sizeof(big_int))));
00432                         }
00433                         else if (bnd->alloc == TRUE)
00434                         {
00435                             if (bnd->type == OCI_CDT_DATETIME)
00436                             {
00437                                 if (bnd->input[j] != NULL)
00438                                 {
00439                                     memcpy(((OCI_Date *) bnd->input[j])->handle,
00440                                            ((ub1 *) bnd->buf.data) + (size_t) (j*bnd->size),
00441                                            sizeof(OCIDate));
00442                                 }
00443                             }
00444 
00445                             /* update bind object indicator pointer with object
00446                              *indicator */
00447 
00448                             if (bnd->type == OCI_CDT_OBJECT)
00449                             {
00450                                 if (bnd->input != NULL)
00451                                 {
00452                                     ((OCI_Object *) bnd->input[j])->tab_ind = bnd->buf.obj_inds[j];
00453                                 }
00454                             }
00455                         }
00456                     }
00457                 }
00458             }
00459 
00460         #ifdef OCI_CHECK_DATASTRINGS
00461 
00462             if (bnd->type == OCI_CDT_TEXT)
00463             {
00464                 for (j = 0; j < bnd->buf.count; j++)
00465                 {
00466                     /* need conversion if bind buffer was allocated */
00467 
00468                     int osize   = -1;
00469                     int offset1 = (bnd->size/sizeof(odtext))*sizeof(dtext);
00470                     int offset2 = bnd->size;
00471 
00472                     if (bnd->buf.lens != NULL)
00473                     {
00474                         osize = (int) ((ub2 *) bnd->buf.lens)[j];
00475                     }
00476 
00477                     if (bnd->size == (sb4) osize)
00478                     {
00479                         osize -= sizeof(odtext);
00480                     }
00481 
00482                     OCI_GetOutputString(((ub1 *) bnd->buf.data) + (j*offset2),
00483                                         ((ub1 *) bnd->input)    + (j*offset1),
00484                                         &osize, sizeof(odtext), sizeof(dtext));
00485 
00486                     /* set zero terminal null character (sometimes it is not set
00487                        by OCI and causes problems if the string has been modified
00488                        and its length reduced */
00489 
00490                     {
00491                         dtext *str = (dtext *) (((ub1 *) bnd->input) + (j*offset1));
00492 
00493                         if (osize> 0)
00494                         {
00495                             str[osize/sizeof(dtext)] = 0;
00496                         }
00497                     }
00498                 }
00499             }
00500             
00501         #endif
00502 
00503         }
00504     }
00505 
00506     return res;
00507 }
00508 
00509 /* --------------------------------------------------------------------------------------------- *
00510  * OCI_BindData
00511  * --------------------------------------------------------------------------------------------- */
00512 
00513 boolean OCI_BindData
00514 (
00515     OCI_Statement *stmt,
00516     void          *data,
00517     ub4            size,
00518     const mtext   *name,
00519     ub1            type,
00520     unsigned int   code,
00521     unsigned int   mode,
00522     unsigned int   subtype,
00523     OCI_TypeInfo  *typinf,
00524     unsigned int   nbelem
00525 )
00526 {
00527     boolean res      = TRUE;
00528     OCI_Bind *bnd    = NULL;
00529     ub4 exec_mode    = OCI_DEFAULT;
00530     boolean is_pltbl = FALSE;
00531     boolean is_array = FALSE;
00532     boolean reused   = FALSE;
00533     ub4 *pnbelem     = NULL;
00534     int index        = 0;
00535     int prev_index   = -1;
00536     size_t nballoc   = (size_t) nbelem;
00537 
00538     /* check index if necessary */
00539 
00540     if (res == TRUE)
00541     {
00542         if (stmt->bind_mode == OCI_BIND_BY_POS)
00543         {
00544             index = (int) mtstol(&name[1], NULL, 10);
00545 
00546             if (index <= 0 || index > OCI_BIND_MAX)
00547             {
00548                 OCI_ExceptionOutOfBounds(stmt->con, index);
00549                 res = FALSE;
00550             }
00551         }
00552     }
00553 
00554     /* check if the bind name has already been used */
00555 
00556     if (res == TRUE)
00557     {
00558         if (mode == OCI_BIND_INPUT)
00559         {
00560             prev_index = OCI_BindGetIndex(stmt, name);
00561 
00562             if (prev_index > 0)
00563             {
00564                 if (stmt->bind_reuse == FALSE)
00565                 {
00566                     OCI_ExceptionBindAlreadyUsed(stmt, name);
00567                     res = FALSE;
00568                 }
00569                 else
00570                 {
00571                     bnd = stmt->ubinds[prev_index-1];
00572 
00573                     if (bnd->type != type)
00574                     {
00575                         OCI_ExceptionRebindBadDatatype(stmt, name);
00576                         res = FALSE;
00577                     }
00578                     else
00579                     {
00580                         reused = TRUE;
00581                     }
00582                 }
00583 
00584                 index = prev_index;
00585             }
00586         }
00587     }
00588 
00589     /* check if we can handle another bind */
00590 
00591     if (res == TRUE)
00592     {
00593         if (mode == OCI_BIND_INPUT)
00594         {
00595             if (stmt->nb_ubinds >= OCI_BIND_MAX)
00596             {
00597                 OCI_ExceptionMaxBind(stmt);
00598                 res = FALSE;
00599             }
00600 
00601             if (res == TRUE)
00602             {
00603                 /* allocate user bind array if necessary */
00604 
00605                 if (stmt->ubinds == NULL)
00606                 {
00607                     stmt->ubinds = (OCI_Bind **) OCI_MemAlloc(OCI_IPC_BIND_ARRAY,
00608                                                               sizeof(*stmt->ubinds),
00609                                                               (size_t) OCI_BIND_MAX,
00610                                                               TRUE);
00611                 }
00612 
00613                 res = (stmt->ubinds != NULL);
00614             }
00615         }
00616         else
00617         {
00618             if (stmt->nb_rbinds >= OCI_BIND_MAX)
00619             {
00620                 OCI_ExceptionMaxBind(stmt);
00621                 res = FALSE;
00622             }
00623 
00624             if (res == TRUE)
00625             {
00626                 /* allocate register bind array if necessary */
00627 
00628                 if (stmt->rbinds == NULL)
00629                 {
00630                     stmt->rbinds = (OCI_Bind **) OCI_MemAlloc(OCI_IPC_BIND_ARRAY,
00631                                                                 sizeof(*stmt->rbinds),
00632                                                                 (size_t) OCI_BIND_MAX,
00633                                                                 TRUE);
00634                 }
00635 
00636                 res = (stmt->rbinds != NULL);
00637             }
00638         }
00639     }
00640 
00641     /* checks done */
00642 
00643     if (res == TRUE)
00644     {
00645         /* check out the number of elements that the bind variable will hold */
00646 
00647         if (nbelem > 0)
00648         {
00649             /* is it a pl/sql table bind ? */
00650 
00651             if (stmt->type == OCI_CST_BEGIN || stmt->type == OCI_CST_DECLARE)
00652             {
00653                 is_pltbl = TRUE;
00654                 is_array = TRUE;
00655             }
00656         }
00657         else
00658         {
00659             nbelem   = stmt->nb_iters;
00660             is_array = stmt->bind_array;
00661         }
00662 
00663         /* compute iterations */
00664         if (nballoc < stmt->nb_iters_init)
00665         {
00666             nballoc = (size_t) stmt->nb_iters_init;
00667         }
00668 
00669         /* create hash table for mapping bind names / index */
00670 
00671         if (stmt->map == NULL)
00672         {
00673             stmt->map = OCI_HashCreate(OCI_HASH_DEFAULT_SIZE, OCI_HASH_INTEGER);
00674 
00675             res = (stmt->map != NULL);
00676         }
00677     }
00678 
00679     /* allocate bind object */
00680 
00681     if (res == TRUE)
00682     {
00683         if (bnd == NULL)
00684         {
00685             bnd = (OCI_Bind *) OCI_MemAlloc(OCI_IPC_BIND, sizeof(*bnd), (size_t) 1, TRUE);
00686         }
00687 
00688         res = (bnd != NULL);
00689     }
00690 
00691     /* allocate indicators array */
00692 
00693     if (res == TRUE)
00694     {
00695         if (bnd->buf.inds == NULL)
00696         {
00697             bnd->buf.inds = (void *) OCI_MemAlloc(OCI_IPC_INDICATOR_ARRAY,
00698                                                   sizeof(sb2), nballoc, TRUE);
00699         }
00700 
00701         res = (bnd->buf.inds != NULL);
00702     }
00703 
00704     /* allocate object indicators pointer array */
00705 
00706     if (res == TRUE)
00707     {
00708         if ((type == OCI_CDT_OBJECT) && (bnd->buf.obj_inds == NULL))
00709         {
00710             bnd->buf.obj_inds = (void *) OCI_MemAlloc(OCI_IPC_INDICATOR_ARRAY,
00711                                                       sizeof(void *), nballoc, TRUE);
00712 
00713             res = (bnd->buf.obj_inds != NULL);
00714         }
00715     }
00716 
00717     /* check need for PL/SQL table extra info */
00718 
00719     if ((res == TRUE) && (is_pltbl == TRUE))
00720     {
00721         bnd->nbelem = nbelem;
00722         pnbelem     = &bnd->nbelem;
00723 
00724         /* allocate array of returned codes */
00725 
00726         if (res == TRUE)
00727         {
00728             if (bnd->plrcds == NULL)
00729             {
00730                 bnd->plrcds = (ub2 *) OCI_MemAlloc(OCI_IPC_PLS_RCODE_ARRAY,
00731                                                    sizeof(ub2), nballoc, TRUE);
00732             }
00733 
00734             res = (bnd->plrcds != NULL);
00735         }
00736     }
00737 
00738     /* for handle based datatypes, we need to allocate an array of handles for
00739        bind calls because OCILIB uses external arrays of OCILIB Objects */
00740 
00741     if ((res == TRUE) && (mode == OCI_BIND_INPUT))
00742     {
00743         if (stmt->bind_alloc_mode == OCI_BAM_EXTERNAL)
00744         {
00745             if (type != OCI_CDT_RAW      &&
00746                 type != OCI_CDT_LONG     &&
00747                 type != OCI_CDT_CURSOR   &&
00748 
00749             #ifndef OCI_CHECK_DATASTRINGS
00750 
00751                 type != OCI_CDT_TEXT     &&
00752 
00753             #endif
00754 
00755                 (type != OCI_CDT_NUMERIC || code == SQLT_VNU)
00756                 )
00757             {
00758                 bnd->alloc = TRUE;
00759 
00760                 if ((reused == TRUE) && (bnd->buf.data != NULL) && (bnd->size != (sb4) size))
00761                 {
00762                     OCI_FREE(bnd->buf.data);
00763                 }
00764 
00765                 if (bnd->buf.data == NULL)
00766                 {
00767                     bnd->buf.data = (void **) OCI_MemAlloc(OCI_IPC_BUFF_ARRAY, (size_t) size,
00768                                                            (size_t) nballoc, TRUE);
00769                 }
00770 
00771                 res = (bnd->buf.data != NULL);
00772             }
00773             else
00774             {
00775                 bnd->buf.data = (void **) data;
00776             }
00777         }
00778     }
00779 
00780     /* setup data length array */
00781 
00782     if ((res == TRUE) && ((type == OCI_CDT_RAW) || (type == OCI_CDT_TEXT)))
00783     {
00784         if (bnd->buf.lens == NULL)
00785         {
00786             bnd->buf.lens = (void *) OCI_MemAlloc(OCI_IPC_LEN_ARRAY, sizeof(ub2), nballoc, TRUE);
00787         }
00788 
00789         res = (bnd->buf.lens != NULL);
00790 
00791         /* initialize length array with buffer default size */
00792 
00793         if (res == TRUE)
00794         {
00795             unsigned int i;
00796 
00797             for (i=0; i < nbelem; i++)
00798             {
00799                 *(ub2*)(((ub1 *)bnd->buf.lens) + sizeof(ub2) * (size_t) i) = (ub2) size;
00800             }
00801         }
00802     }
00803 
00804     /* initialize bind object */
00805 
00806     if (res == TRUE)
00807     {
00808         /* initialize bind attributes */
00809 
00810         bnd->stmt      = stmt;
00811         bnd->input     = (void **) data;
00812         bnd->type      = type;
00813         bnd->size      = size;
00814         bnd->code      = (ub2) code;
00815         bnd->subtype   = (ub1) subtype;
00816         bnd->is_array  = is_array;
00817         bnd->csfrm     = OCI_CSF_NONE;
00818         bnd->direction = OCI_BDM_IN_OUT;
00819 
00820         if (bnd->name == NULL)
00821         {
00822             bnd->name = mtsdup(name);
00823         }
00824 
00825         /* initialize buffer */
00826 
00827         bnd->buf.count   = nbelem;
00828         bnd->buf.sizelen = sizeof(ub2);
00829 
00830         /* internal allocation if needed */
00831 
00832         if ((data == NULL) && (stmt->bind_alloc_mode == OCI_BAM_INTERNAL))
00833         {
00834             res = OCI_BindAllocData(bnd);
00835         }
00836 
00837         /* if we bind an OCI_Long or any output bind, we need to change the
00838            execution mode to provide data at execute time */
00839 
00840         if (bnd->type == OCI_CDT_LONG)
00841         {
00842             OCI_Long *lg = (OCI_Long *)  bnd->input;
00843 
00844             lg->maxsize = size;
00845             exec_mode   = OCI_DATA_AT_EXEC;
00846 
00847             if (bnd->subtype == OCI_CLONG)
00848             {
00849                 lg->maxsize /= (unsigned int) sizeof(dtext);
00850                 lg->maxsize *= (unsigned int) sizeof(odtext);
00851             }
00852         }
00853         else if (mode == OCI_BIND_OUTPUT)
00854         {
00855             exec_mode = OCI_DATA_AT_EXEC;
00856         }
00857     }
00858 
00859     /* OCI binding */
00860 
00861     if (res == TRUE)
00862     {
00863         if (stmt->bind_mode == OCI_BIND_BY_POS)
00864         {
00865             OCI_CALL1
00866             (
00867                 res, stmt->con, stmt,
00868 
00869                 OCIBindByPos(stmt->stmt, (OCIBind **) &bnd->buf.handle,
00870                              stmt->con->err, (ub4) index, (void *) bnd->buf.data,
00871                              bnd->size, bnd->code, bnd->buf.inds, (ub2 *) bnd->buf.lens,
00872                              bnd->plrcds, (ub4) (is_pltbl == TRUE ? nbelem : 0),
00873                              pnbelem, exec_mode)
00874             )
00875         }
00876         else
00877         {
00878             void * ostr = NULL;
00879             int osize   = -1;
00880 
00881             ostr = OCI_GetInputMetaString(bnd->name, &osize);
00882 
00883             OCI_CALL1
00884             (
00885                 res, stmt->con, stmt,
00886 
00887                 OCIBindByName(stmt->stmt, (OCIBind **) &bnd->buf.handle,
00888                               stmt->con->err, (OraText *) ostr, (sb4) osize,
00889                               (void *) bnd->buf.data, bnd->size, bnd->code,
00890                               bnd->buf.inds, (ub2 *) bnd->buf.lens, bnd->plrcds,
00891                               (ub4) (is_pltbl == TRUE ? nbelem : 0),
00892                               pnbelem, exec_mode)
00893             )
00894 
00895             OCI_ReleaseMetaString(ostr);
00896         }
00897 
00898         if (code == SQLT_NTY || code == SQLT_REF)
00899         {
00900             OCI_CALL1
00901             (
00902                 res, stmt->con, stmt,
00903 
00904                 OCIBindObject((OCIBind *) bnd->buf.handle, stmt->con->err,
00905                               (OCIType *) typinf->tdo, (void **) bnd->buf.data,
00906                               (ub4 *) NULL, (void **) bnd->buf.obj_inds,
00907                               (ub4 *) bnd->buf.inds)
00908             )
00909         }
00910 
00911         if (mode == OCI_BIND_OUTPUT)
00912         {
00913             /* register output placeholder */
00914 
00915             OCI_CALL1
00916             (
00917                 res, stmt->con, stmt,
00918 
00919                 OCIBindDynamic((OCIBind *) bnd->buf.handle, stmt->con->err,
00920                                (dvoid *) bnd, OCI_ProcInBind,
00921                                (dvoid *) bnd, OCI_ProcOutBind)
00922             )
00923         }
00924     }
00925 
00926     /* set charset form */
00927 
00928     if (res == TRUE)
00929     {
00930         if ((bnd->type == OCI_CDT_LOB) && (bnd->subtype == OCI_NCLOB))
00931         {
00932             ub1 csfrm = SQLCS_NCHAR;
00933 
00934             OCI_CALL1
00935             (
00936                 res, bnd->stmt->con, bnd->stmt,
00937 
00938                 OCIAttrSet((dvoid *) bnd->buf.handle,
00939                            (ub4    ) OCI_HTYPE_BIND,
00940                            (dvoid *) &csfrm,
00941                            (ub4    ) sizeof(csfrm),
00942                            (ub4    ) OCI_ATTR_CHARSET_FORM,
00943                            bnd->stmt->con->err)
00944             )
00945         }
00946     }
00947 
00948     /* set charset ID */
00949 
00950     if (res == TRUE)
00951     {
00952         if ((bnd->type == OCI_CDT_TEXT)  ||
00953             ((bnd->type == OCI_CDT_LOB)   && (bnd->subtype != OCI_BLOB))  ||
00954             ((bnd->type == OCI_CDT_LONG)  && (bnd->subtype != OCI_BLONG)))
00955         {
00956 
00957         #ifdef OCI_CHARSET_MIXED
00958 
00959             /* setup Unicode mode for user data on mixed builds */
00960             {
00961                 ub2 csid = OCI_UTF16ID;
00962 
00963                 OCI_CALL1
00964                 (
00965                     res, bnd->stmt->con, bnd->stmt,
00966 
00967                     OCIAttrSet((dvoid *) bnd->buf.handle,
00968                                (ub4    ) OCI_HTYPE_BIND,
00969                                (dvoid *) &csid,
00970                                (ub4    ) sizeof(csid),
00971                                (ub4    ) OCI_ATTR_CHARSET_ID,
00972                                bnd->stmt->con->err)
00973                 )
00974             }
00975 
00976         #endif
00977 
00978         }
00979     }
00980 
00981 /*
00982     this call was removed in v3.6.0
00983     It will be restored in future version, but need more testing on all builds
00984 
00985     if (bnd->type == OCI_CDT_TEXT)
00986     {
00987         OCI_CALL1
00988         (
00989             res, stmt->con, stmt,
00990 
00991             OCIAttrSet((dvoid *) bnd->buf.handle, (ub4) OCI_HTYPE_BIND,
00992                        (dvoid *) &bnd->size, (ub4) sizeof(bnd->size),
00993                        (ub4) OCI_ATTR_MAXDATA_SIZE,  bnd->stmt->con->err)
00994         )
00995     }
00996 */
00997 
00998     /* on success, we :
00999          - add the bind handle to the bind array
01000          - add the bind index to the map
01001     */
01002 
01003     if (res == TRUE)
01004     {
01005         if (mode == OCI_BIND_INPUT)
01006         {
01007             if (reused == FALSE)
01008             {
01009                 stmt->ubinds[stmt->nb_ubinds++] = bnd;
01010 
01011                 /* for user binds, add a positive index */
01012 
01013                 OCI_HashAddInt(stmt->map, name, stmt->nb_ubinds);
01014             }
01015         }
01016         else
01017         {
01018             /* for register binds, add a negative index */
01019 
01020             stmt->rbinds[stmt->nb_rbinds++] = bnd;
01021 
01022             index = (int) stmt->nb_rbinds;
01023 
01024             OCI_HashAddInt(stmt->map, name, -index);
01025         }
01026     }
01027 
01028     if (res == FALSE)
01029     {
01030         if ((bnd != NULL) && (prev_index  == -1))
01031         {
01032             OCI_BindFree(bnd);
01033         }
01034     }
01035 
01036     OCI_RESULT(res);
01037 
01038     return res;
01039 }
01040 
01041 /* --------------------------------------------------------------------------------------------- *
01042  * OCI_BindGetIndex
01043  * --------------------------------------------------------------------------------------------- */
01044 
01045 int OCI_BindGetIndex
01046 (
01047     OCI_Statement *stmt,
01048     const mtext   *name
01049 )
01050 {
01051     OCI_HashEntry *he = NULL;
01052     int index         = -1;
01053 
01054     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, -1);
01055     OCI_CHECK_PTR(OCI_IPC_STRING, name, -1);
01056 
01057     if (stmt->map != NULL)
01058     {
01059         he = OCI_HashLookup(stmt->map, name, FALSE);
01060 
01061         while (he != NULL)
01062         {
01063             /* no more entries or key matched => so we got it ! */
01064 
01065             if (he->next == NULL || mtscasecmp(he->key, name) == 0)
01066             {
01067                 /* in order to sue the same map for user binds and
01068                    register binds :
01069                       - user binds are stored as positive values
01070                       - registers binds are stored as negatives values
01071                 */
01072 
01073                 index = he->values->value.num;
01074 
01075                 if (index < 0)
01076                 {
01077                     index = -index;
01078                 }
01079 
01080                 break;
01081             }
01082         }
01083     }
01084 
01085     return index;
01086 }
01087 
01088 /* --------------------------------------------------------------------------------------------- *
01089  * OCI_FetchIntoUserVariables
01090  * --------------------------------------------------------------------------------------------- */
01091 
01092 boolean OCI_FetchIntoUserVariables
01093 (
01094     OCI_Statement *stmt,
01095     va_list        args
01096 )
01097 {
01098     OCI_Resultset *rs = NULL;
01099     boolean res       = FALSE;
01100    
01101     /* get resultset */
01102 
01103     rs = OCI_GetResultset(stmt);
01104 
01105     /* fetch data */
01106 
01107     if (rs != NULL)
01108     {
01109         res = OCI_FetchNext(rs);
01110     }
01111 
01112     if (res == TRUE)
01113     {
01114         unsigned int i, n;
01115         
01116         /* loop on column list for updating user given placeholders */
01117 
01118         for (i = 1, n = OCI_GetColumnCount(rs); (i <= n) && (res == TRUE); i++)
01119         {
01120             OCI_Column *col = OCI_GetColumn(rs, i);
01121 
01122             int type = va_arg(args, int);
01123 
01124             switch (type)
01125             {
01126                 case OCI_ARG_SHORT:
01127                 {
01128                     short src, *dst;
01129 
01130                     src = OCI_GetShort(rs, i);
01131                     dst = va_arg(args, short *);
01132 
01133                     if (dst != NULL)
01134                     {
01135                         *dst = src;
01136                     }
01137 
01138                     break;
01139                 }
01140                 case OCI_ARG_USHORT:
01141                 {
01142                     unsigned short src, *dst;
01143 
01144                     src = OCI_GetUnsignedShort(rs, i);
01145                     dst = va_arg(args, unsigned short *);
01146 
01147                     if (dst != NULL)
01148                     {
01149                         *dst = src;
01150                     }
01151 
01152                     break;
01153                 }
01154                 case OCI_ARG_INT:
01155                 {
01156                     int src, *dst;
01157 
01158                     src = OCI_GetInt(rs, i);
01159                     dst = va_arg(args, int *);
01160 
01161                     if (dst != NULL)
01162                     {
01163                         *dst = src;
01164                     }
01165 
01166                     break;
01167                 }
01168                 case OCI_ARG_UINT:
01169                 {
01170                     unsigned int src, *dst;
01171 
01172                     src = OCI_GetUnsignedInt(rs, i);
01173                     dst = va_arg(args, unsigned int *);
01174 
01175                     if (dst != NULL)
01176                     {
01177                         *dst = src;
01178                     }
01179 
01180                     break;
01181                 }
01182                 case OCI_ARG_BIGINT:
01183                 {
01184                     big_int src, *dst;
01185 
01186                     src = OCI_GetBigInt(rs, i);
01187                     dst = va_arg(args, big_int *);
01188 
01189                     if (dst != NULL)
01190                     {
01191                         *dst = src;
01192                     }
01193 
01194                     break;
01195                 }
01196                 case OCI_ARG_BIGUINT:
01197                 {
01198                     big_uint src, *dst;
01199 
01200                     src = OCI_GetUnsignedBigInt(rs, i);
01201                     dst = va_arg(args, big_uint *);
01202 
01203                     if (dst != NULL)
01204                     {
01205                         *dst = src;
01206                     }
01207 
01208                     break;
01209                 }
01210                 case OCI_ARG_DOUBLE:
01211                 {
01212                     double src, *dst;
01213 
01214                     src = OCI_GetDouble(rs, i);
01215                     dst = va_arg(args, double *);
01216 
01217                     if (dst != NULL)
01218                     {
01219                         *dst = src;
01220                     }
01221 
01222                     break;
01223                 }
01224                 case OCI_ARG_FLOAT:
01225                 {
01226                     float src, *dst;
01227 
01228                     src = OCI_GetFloat(rs, i);
01229                     dst = va_arg(args, float *);
01230 
01231                     if (dst != NULL)
01232                     {
01233                         *dst = src;
01234                     }
01235 
01236                     break;
01237                 }
01238                 case OCI_ARG_DATETIME:
01239                 {
01240                     OCI_Date *src, *dst;
01241 
01242                     src = OCI_GetDate(rs, i);
01243                     dst = (OCI_Date *) va_arg(args, OCI_Date *);
01244 
01245                     if ((src != NULL) && (dst != NULL))
01246                     {
01247                         res = OCI_DateAssign(dst, src);
01248                     }
01249 
01250                     break;
01251                 }
01252                 case OCI_ARG_TEXT:
01253                 {
01254                     const dtext *src;
01255                     dtext *dst;
01256 
01257                     src = OCI_GetString(rs, i);
01258                     dst = va_arg(args, dtext *);
01259 
01260                     if (dst != NULL)
01261                     {
01262                         dst[0] = 0;
01263                     }
01264 
01265                     if ((dst != NULL) && (src != NULL))
01266                     {
01267                         dtscat(dst, src);
01268                     }
01269 
01270                     break;
01271                 }
01272                 case OCI_ARG_RAW:
01273                 {
01274                     OCI_GetRaw(rs, i, va_arg(args, dtext *), col->bufsize);
01275                     break;
01276                 }
01277                 case OCI_ARG_LOB:
01278                 {
01279                     OCI_Lob *src, *dst;
01280 
01281                     src = OCI_GetLob(rs, i);
01282                     dst = (OCI_Lob *) va_arg(args, OCI_Lob *);
01283 
01284                     if ((dst != NULL) && (src != NULL))
01285                     {
01286                         res = OCI_LobAssign(dst, src);
01287                     }
01288 
01289                     break;
01290                 }
01291                 case OCI_ARG_FILE:
01292                 {
01293                     OCI_File *src, *dst;
01294 
01295                     src = OCI_GetFile(rs, i);
01296                     dst = (OCI_File *) va_arg(args, OCI_File *);
01297 
01298                     if ((dst != NULL) && (src != NULL))
01299                     {
01300                         res = OCI_FileAssign(dst, src);
01301                     }
01302 
01303                     break;
01304                 }
01305                 case OCI_ARG_TIMESTAMP:
01306                 {
01307                     OCI_Timestamp *src, *dst;
01308 
01309                     src = OCI_GetTimestamp(rs, i);
01310                     dst = (OCI_Timestamp *) va_arg(args, OCI_Timestamp *);
01311 
01312                     if ((dst != NULL) && (src != NULL))
01313                     {
01314                         res = OCI_TimestampAssign(dst, src);
01315                     }
01316 
01317                     break;
01318                 }
01319                 case OCI_ARG_INTERVAL:
01320                 {
01321                     OCI_Interval *src, *dst;
01322 
01323                     src = OCI_GetInterval(rs, i);
01324                     dst = (OCI_Interval *) va_arg(args, OCI_Interval *);
01325 
01326                     if ((dst != NULL) && (src != NULL))
01327                     {
01328                         res = OCI_IntervalAssign(dst, src);
01329                     }
01330 
01331                     break;
01332                 }
01333                 case OCI_ARG_OBJECT:
01334                 {
01335                     OCI_Object *src, *dst;
01336 
01337                     src = OCI_GetObject(rs, i);
01338                     dst = (OCI_Object *) va_arg(args, OCI_Object *);
01339 
01340                     if ((dst != NULL) && (src != NULL))
01341                     {
01342                         res = OCI_ObjectAssign(dst, src);
01343                     }
01344 
01345                     break;
01346                 }
01347                 case OCI_ARG_COLLECTION:
01348                 {
01349                     OCI_Coll *src, *dst;
01350 
01351                     src = OCI_GetColl(rs, i);
01352                     dst = (OCI_Coll *) va_arg(args, OCI_Coll *);
01353 
01354                     if ((dst != NULL) && (src != NULL))
01355                     {
01356                         res =OCI_CollAssign(dst, src);
01357                     }
01358 
01359                     break;
01360                 }
01361                 case OCI_ARG_REF:
01362                 {
01363                     OCI_Ref *src, *dst;
01364 
01365                     src = OCI_GetRef(rs, i);
01366                     dst = (OCI_Ref *) va_arg(args, OCI_Ref *);
01367 
01368                     if ((dst != NULL) && (src != NULL))
01369                     {
01370                         res =OCI_RefAssign(dst, src);
01371                     }
01372 
01373                     break;
01374                 }
01375                 default:
01376                 {
01377                     OCI_ExceptionMappingArgument(stmt->con, stmt, type);
01378 
01379                     res = FALSE;
01380 
01381                     break;
01382                 }
01383             }
01384         }
01385     }
01386 
01387     return res;
01388 }
01389 
01390 /* --------------------------------------------------------------------------------------------- *
01391  * OCI_StatementInit
01392  * --------------------------------------------------------------------------------------------- */
01393 
01394 OCI_Statement * OCI_StatementInit
01395 (
01396     OCI_Connection *con,
01397     OCI_Statement **pstmt,
01398     OCIStmt        *handle,
01399     OCI_Define     *def
01400 )
01401 {
01402     OCI_Statement * stmt = NULL;
01403     boolean res          = TRUE;
01404 
01405     OCI_CHECK(pstmt == NULL, NULL);
01406 
01407     if (*pstmt == NULL)
01408     {
01409         *pstmt = (OCI_Statement *) OCI_MemAlloc(OCI_IPC_STATEMENT, sizeof(*stmt), (size_t) 1, TRUE);
01410     }
01411 
01412     if (*pstmt != NULL)
01413     {
01414         stmt = *pstmt;
01415 
01416         stmt->con  = con;
01417         stmt->stmt = handle;
01418 
01419         stmt->exec_mode       = OCI_DEFAULT;
01420         stmt->long_size       = OCI_SIZE_LONG;
01421         stmt->bind_reuse      = FALSE;
01422         stmt->bind_mode       = OCI_BIND_BY_NAME;
01423         stmt->long_mode       = OCI_LONG_EXPLICIT;
01424         stmt->bind_alloc_mode = OCI_BAM_EXTERNAL;
01425 
01426         /* reset statement */
01427 
01428         OCI_StatementReset(stmt);
01429 
01430         if (def == NULL)
01431         {
01432             /* allocate handle for non fetched cursor */
01433 
01434             stmt->hstate = OCI_OBJECT_ALLOCATED;
01435         }
01436         else
01437         {
01438             stmt->hstate = OCI_OBJECT_FETCHED_CLEAN;
01439             stmt->status = OCI_STMT_PREPARED  | OCI_STMT_PARSED | 
01440                            OCI_STMT_DESCRIBED | OCI_STMT_EXECUTED;
01441             stmt->type   = OCI_CST_SELECT;
01442 
01443             res = (res && OCI_SetPrefetchSize(stmt, OCI_PREFETCH_SIZE));
01444             res = (res && OCI_SetFetchSize(stmt, OCI_FETCH_SIZE));
01445 
01446             /* not really perfect, but better than nothing */
01447 
01448             if (def->col.name != NULL)
01449             {
01450                 stmt->sql = mtsdup(def->col.name);
01451             }
01452         }
01453     }
01454 
01455     /* check for failurec */
01456 
01457     if (res == FALSE)
01458     {
01459         OCI_StatementFree(stmt);
01460         stmt = NULL;
01461     }
01462 
01463     return stmt;
01464 }
01465 
01466 /* --------------------------------------------------------------------------------------------- *
01467  * OCI_StatementReset
01468  * --------------------------------------------------------------------------------------------- */
01469 
01470 boolean OCI_StatementReset
01471 (
01472     OCI_Statement *stmt
01473 )
01474 {
01475     boolean res = TRUE;
01476 
01477     /* reset batch errors */
01478 
01479     res = OCI_BatchErrorClear(stmt);
01480 
01481     /* free resultsets */
01482 
01483     res = OCI_ReleaseResultsets(stmt);
01484 
01485     /* free in/out binds */
01486 
01487     res = OCI_BindFreeAll(stmt);
01488 
01489     /* free bind map */
01490 
01491     if (stmt->map != NULL)
01492     {
01493         OCI_HashFree(stmt->map);
01494     }
01495 
01496     /* free handle if needed */
01497 
01498     if (stmt->stmt != NULL)
01499     {
01500         if (stmt->hstate == OCI_OBJECT_ALLOCATED)
01501         {
01502 
01503         #if OCI_VERSION_COMPILE >= OCI_9_2
01504 
01505 
01506             if (OCILib.version_runtime >= OCI_9_2)
01507             {
01508                 OCIStmtRelease(stmt->stmt, stmt->con->err, NULL, 0, OCI_DEFAULT);
01509             }
01510             else
01511 
01512         #endif
01513 
01514             {
01515                 OCI_HandleFree((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT);
01516             }
01517                 
01518             stmt->stmt = NULL;
01519         }
01520         else if (stmt->hstate == OCI_OBJECT_ALLOCATED_BIND_STMT)
01521         {  
01522             OCI_HandleFree((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT);
01523 
01524             stmt->stmt = NULL;
01525         }
01526     }
01527 
01528     /* free sql statement */
01529 
01530     OCI_FREE(stmt->sql);
01531 
01532     stmt->rsts  = NULL;
01533     stmt->sql   = NULL;
01534     stmt->map   = NULL;
01535     stmt->batch = NULL;
01536 
01537     stmt->status     = OCI_STMT_CLOSED;
01538     stmt->type       = OCI_UNKNOWN;
01539     stmt->bind_array = FALSE;
01540 
01541     stmt->nb_iters      = 1;
01542     stmt->nb_iters_init = 1;
01543     stmt->dynidx        = 0;
01544     stmt->err_pos       = 0;
01545 
01546     return res;
01547 }
01548 
01549 /* --------------------------------------------------------------------------------------------- *
01550  * OCI_StatementClose
01551  * --------------------------------------------------------------------------------------------- */
01552 
01553 boolean OCI_StatementClose
01554 (
01555     OCI_Statement *stmt
01556 )
01557 {
01558     boolean res    = TRUE;
01559     OCI_Error *err = NULL;
01560 
01561     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01562 
01563     /* clear statement reference from current error object */
01564 
01565     err = OCI_ErrorGet(FALSE, FALSE);
01566 
01567     if (err != NULL && err->stmt == stmt)
01568     {
01569         err->stmt = NULL;
01570     }
01571 
01572     /* reset data */
01573 
01574     res = OCI_StatementReset(stmt);
01575 
01576     return res;
01577 }
01578 
01579 /* --------------------------------------------------------------------------------------------- *
01580  * OCI_BatchErrorClear
01581  * --------------------------------------------------------------------------------------------- */
01582 
01583 boolean OCI_BatchErrorClear
01584 (
01585     OCI_Statement *stmt
01586 )
01587 {
01588     boolean res = TRUE;
01589 
01590     if (stmt->batch != NULL)
01591     {
01592         /* free internal array of OCI_Errors */
01593 
01594         OCI_FREE(stmt->batch->errs);
01595 
01596         /* free batch structure */
01597 
01598         OCI_FREE(stmt->batch);
01599     }
01600 
01601     return res;
01602 }
01603 
01604 /* --------------------------------------------------------------------------------------------- *
01605  * OCI_BatchErrorsInit
01606  * --------------------------------------------------------------------------------------------- */
01607 
01608 boolean OCI_BatchErrorInit
01609 (
01610     OCI_Statement *stmt
01611 )
01612 {
01613     boolean res   = TRUE;
01614     ub4 err_count = 0;
01615 
01616     OCI_BatchErrorClear(stmt);
01617 
01618     /* all OCI call here are not checked for errors as we already dealing
01619        with an array DML error */
01620 
01621     OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
01622                (dvoid *) &err_count, (ub4 *) NULL,
01623                (ub4) OCI_ATTR_NUM_DML_ERRORS, stmt->con->err);
01624 
01625     if (err_count > 0)
01626     {
01627         OCIError *hndl = NULL;
01628 
01629         /* allocate batch error structure */
01630 
01631         stmt->batch = (OCI_BatchErrors *) OCI_MemAlloc(OCI_IPC_BATCH_ERRORS,
01632                                                        sizeof(*stmt->batch),
01633                                                        (size_t) 1, TRUE);
01634 
01635         res = (stmt->batch != NULL);
01636 
01637         /* allocate array of error objects */
01638 
01639         if (res == TRUE)
01640         {
01641             stmt->batch->errs = (OCI_Error *) OCI_MemAlloc(OCI_IPC_ERROR,
01642                                                            sizeof(*stmt->batch->errs),
01643                                                            (size_t) err_count, TRUE);
01644 
01645             res = (stmt->batch->errs != NULL);
01646         }
01647 
01648         if (res == TRUE)
01649         {
01650             /* allocate OCI error handle */
01651 
01652             OCI_HandleAlloc((dvoid  *) stmt->con->env,
01653                             (dvoid **) (void *) &hndl,
01654                             (ub4) OCI_HTYPE_ERROR,
01655                             (size_t) 0, (dvoid **) NULL);
01656 
01657             res = (hndl != NULL);
01658         }
01659 
01660         /* loop on the OCI errors to fill OCILIB error objects */
01661 
01662         if (res == TRUE)
01663         {
01664             ub4 i;
01665 
01666             stmt->batch->count = err_count;
01667 
01668             for (i = 0; i < stmt->batch->count; i++)
01669             {
01670                 int osize  = -1;
01671                 void *ostr = NULL;
01672 
01673                 OCI_Error *err = &stmt->batch->errs[i];
01674 
01675                 OCIParamGet((dvoid *) stmt->con->err, OCI_HTYPE_ERROR,
01676                             stmt->con->err, (dvoid **) (void *) &hndl, i);
01677 
01678                 /* get row offset */
01679 
01680                 OCIAttrGet((dvoid *) hndl, (ub4) OCI_HTYPE_ERROR,
01681                            (void *) &err->row, (ub4 *) NULL,
01682                            (ub4) OCI_ATTR_DML_ROW_OFFSET, stmt->con->err);
01683 
01684                 /* fill error attributes */
01685 
01686                 err->type = OCI_ERR_ORACLE;
01687                 err->con  = stmt->con;
01688                 err->stmt = stmt;
01689 
01690                 /* OCILIB indexes start at 1 */
01691 
01692                 err->row++;
01693 
01694                 /* get error string */
01695 
01696                 osize = (int) msizeof(err->str) - 1;
01697 
01698                 ostr = OCI_GetInputMetaString(err->str, &osize);
01699 
01700                 OCIErrorGet((dvoid *) hndl,
01701                             (ub4) 1,
01702                             (OraText *) NULL, &err->ocode,
01703                             (OraText *) ostr,
01704                             (ub4) osize,
01705                             (ub4) OCI_HTYPE_ERROR);
01706 
01707                 OCI_GetOutputMetaString(ostr, err->str, &osize);
01708                 OCI_ReleaseMetaString(ostr);
01709             }
01710         }
01711 
01712         /* release error handle */
01713 
01714         if (hndl != NULL)
01715         {
01716             OCI_HandleFree(hndl, OCI_HTYPE_ERROR);
01717         }
01718     }
01719 
01720     return res;
01721 }
01722 
01723 /* --------------------------------------------------------------------------------------------- *
01724  * OCI_ExecuteInternal
01725  * --------------------------------------------------------------------------------------------- */
01726 
01727 boolean OCI_API OCI_ExecuteInternal
01728 (
01729     OCI_Statement *stmt,
01730     ub4            mode
01731 )
01732 {
01733     boolean res  = TRUE;
01734     sword status = OCI_SUCCESS;
01735     ub4 iters    = 0;
01736 
01737     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01738     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_PREPARED, FALSE);
01739 
01740     /* set up iters and mode values for execution */
01741 
01742     if (stmt->type == OCI_CST_SELECT)
01743     {
01744         mode |= stmt->exec_mode;
01745     }
01746     else
01747     {
01748         iters = stmt->nb_iters;
01749 
01750         /* for array DML, use batch error mode */
01751 
01752         if (iters > 1)
01753         {
01754             mode = mode | OCI_BATCH_ERRORS;
01755         }
01756     }
01757 
01758     /* reset batch errors */
01759 
01760     OCI_BatchErrorClear(stmt);
01761 
01762     /* check bind objects for updating their null indicator status */
01763 
01764     res = res && OCI_BindCheck(stmt);
01765 
01766     /* check current resultsets */
01767 
01768     if ((res == TRUE) && (stmt->rsts != NULL))
01769     {
01770         /* resultsets are freed before any prepare operations.
01771            So, if we got ones here, it means the same SQL order
01772            is re-executed */
01773 
01774         if (stmt->type == OCI_CST_SELECT)
01775         {
01776             /* just reinitialize the current resultet */
01777 
01778             res = OCI_ResultsetInit(stmt->rsts[0]);
01779         }
01780         else
01781         {
01782             /* Must free previous resulsets for 'returning into'
01783                SQL orders that can produce multiple resulsets */
01784 
01785             res = OCI_ReleaseResultsets(stmt);
01786         }
01787     }
01788 
01789     /* Oracle execute call */
01790 
01791     status = OCIStmtExecute(stmt->con->cxt, stmt->stmt, stmt->con->err, iters,
01792                             (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, mode);
01793 
01794     /* reset input binds indicators status even if execution failed */
01795 
01796     OCI_BindReset(stmt);
01797 
01798     /* check result */
01799 
01800     res = ((status == OCI_SUCCESS) ||
01801            (status == OCI_SUCCESS_WITH_INFO) ||
01802            (status == OCI_NEED_DATA));
01803 
01804     if (status == OCI_SUCCESS_WITH_INFO)
01805     {
01806         OCI_ExceptionOCI(stmt->con->err, stmt->con, stmt, TRUE);
01807     }
01808 
01809     /* on batch mode, check if any error occured */
01810 
01811     if (mode & OCI_BATCH_ERRORS)
01812     {
01813         /* build batch error list if the statement is array DML */
01814 
01815         OCI_BatchErrorInit(stmt);
01816 
01817         if (stmt->batch != NULL)
01818         {
01819             res = (stmt->batch->count == 0);
01820         }
01821     }
01822 
01823     /* update status on success */
01824 
01825     if (res == TRUE)
01826     {
01827         if (mode & OCI_PARSE_ONLY)
01828         {
01829             stmt->status |= OCI_STMT_PARSED;
01830         }
01831         else if (mode & OCI_DESCRIBE_ONLY)
01832         {
01833             stmt->status |= OCI_STMT_PARSED;
01834             stmt->status |= OCI_STMT_DESCRIBED;
01835         }
01836         else
01837         {
01838             stmt->status |= OCI_STMT_PARSED;
01839             stmt->status |= OCI_STMT_DESCRIBED;
01840             stmt->status |= OCI_STMT_EXECUTED;
01841 
01842             /* commit if necessary */
01843 
01844             if (stmt->con->autocom == TRUE)
01845             {
01846                 OCI_Commit(stmt->con);
01847             }
01848         }
01849     }
01850     else
01851     {
01852         /* get parse error position type */
01853 
01854         /* (one of the rare OCI call not enclosed with a OCI_CALLX macro ...) */
01855 
01856         OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
01857                    (dvoid *) &stmt->err_pos, (ub4 *) NULL,
01858                    (ub4) OCI_ATTR_PARSE_ERROR_OFFSET, stmt->con->err);
01859 
01860         /* raise exception */
01861 
01862         OCI_ExceptionOCI(stmt->con->err, stmt->con, stmt, FALSE);
01863     }
01864 
01865     OCI_RESULT(res);
01866 
01867     return res;
01868 }
01869 
01870 /* ********************************************************************************************* *
01871  *                            PUBLIC FUNCTIONS
01872  * ********************************************************************************************* */
01873 
01874 /* --------------------------------------------------------------------------------------------- *
01875  * OCI_StatementCreate
01876  * --------------------------------------------------------------------------------------------- */
01877 
01878 OCI_Statement * OCI_API OCI_StatementCreate
01879 (
01880     OCI_Connection *con
01881 )
01882 {
01883     OCI_Statement *stmt = NULL;
01884     OCI_Item *item      = NULL;
01885 
01886     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01887 
01888     /* create statement object */
01889 
01890     item = OCI_ListAppend(con->stmts, sizeof(*stmt));
01891 
01892     if (item != NULL)
01893     {
01894         stmt = OCI_StatementInit(con, (OCI_Statement **) &item->data, NULL, FALSE);
01895     }
01896 
01897     OCI_RESULT(stmt != NULL);
01898 
01899     return stmt;
01900 }
01901 
01902 /* --------------------------------------------------------------------------------------------- *
01903  * OCI_StatementFree
01904  * --------------------------------------------------------------------------------------------- */
01905 
01906 boolean OCI_API OCI_StatementFree
01907 (
01908     OCI_Statement *stmt
01909 )
01910 {
01911     boolean res = FALSE;
01912 
01913     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01914 
01915     OCI_CHECK_OBJECT_FETCHED(stmt, FALSE);
01916 
01917     res = OCI_StatementClose(stmt);
01918 
01919     OCI_ListRemove(stmt->con->stmts, stmt);
01920 
01921     OCI_FREE(stmt);
01922 
01923     OCI_RESULT(res);
01924 
01925     return res;
01926 }
01927 
01928 /* --------------------------------------------------------------------------------------------- *
01929  * OCI_ReleaseResultsets
01930  * --------------------------------------------------------------------------------------------- */
01931 
01932 boolean OCI_API OCI_ReleaseResultsets
01933 (
01934     OCI_Statement *stmt
01935 )
01936 {
01937     boolean res = TRUE;
01938     ub4 nb_err = 0;
01939 
01940     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01941 
01942     if (stmt->rsts != NULL)
01943     {
01944         ub4 i;
01945         
01946         for (i = 0; i  < stmt->nb_rs; i++)
01947         {
01948             if (stmt->rsts[i] != NULL)
01949             {
01950                 if (FALSE == OCI_ResultsetFree(stmt->rsts[i]))
01951                 {
01952                     nb_err++;
01953                 }
01954             }
01955         }
01956 
01957         OCI_FREE(stmt->rsts);
01958     }
01959 
01960     res = (nb_err == 0);
01961 
01962     OCI_RESULT(res);
01963 
01964     return res;
01965 }
01966 
01967 /* --------------------------------------------------------------------------------------------- *
01968  * OCI_Prepare
01969  * --------------------------------------------------------------------------------------------- */
01970 
01971 boolean OCI_API OCI_Prepare
01972 (
01973     OCI_Statement *stmt,
01974     const mtext   *sql
01975 )
01976 {
01977     boolean res = TRUE;
01978     void *ostr  = NULL;
01979     int osize   = -1;
01980 
01981     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01982     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
01983 
01984     /* reset statement */
01985 
01986     res = OCI_StatementReset(stmt);
01987 
01988     if (res == TRUE)
01989     {
01990         /* store SQL */
01991 
01992         stmt->sql = mtsdup(sql);
01993 
01994         ostr = OCI_GetInputMetaString(stmt->sql, &osize);
01995 
01996         if (OCILib.version_runtime < OCI_9_2)
01997         {
01998             /* allocate handle */
01999 
02000             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) stmt->con->env,
02001                                                   (dvoid **) (void *) &stmt->stmt,
02002                                                   (ub4) OCI_HTYPE_STMT,
02003                                                   (size_t) 0, (dvoid **) NULL));
02004         }
02005     }
02006 
02007     if (res == TRUE)
02008     {
02009         /* prepare SQL */
02010 
02011     #if OCI_VERSION_COMPILE >= OCI_9_2
02012 
02013         if (OCILib.version_runtime >= OCI_9_2)
02014         {
02015             OCI_CALL1
02016             (
02017                 res, stmt->con, stmt,
02018 
02019                 OCIStmtPrepare2(stmt->con->cxt, &stmt->stmt, stmt->con->err, (OraText *) ostr,
02020                                (ub4) osize, NULL, 0, (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)
02021             )
02022         }
02023         else
02024 
02025     #endif
02026 
02027         {
02028             OCI_CALL1
02029             (
02030                 res, stmt->con, stmt,
02031 
02032                 OCIStmtPrepare(stmt->stmt,stmt->con->err, (OraText *) ostr,
02033                                (ub4) osize, (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)
02034             )
02035         }
02036 
02037         OCI_ReleaseMetaString(ostr);
02038 
02039         /* get statement type */
02040 
02041         OCI_CALL1
02042         (
02043             res, stmt->con, stmt,
02044 
02045             OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
02046                        (dvoid *) &stmt->type, (ub4 *) NULL,
02047                        (ub4) OCI_ATTR_STMT_TYPE, stmt->con->err)
02048         )
02049     }
02050 
02051     /* update statement status */
02052 
02053     if (res == TRUE)
02054     {
02055         ub4 size = 0;
02056 
02057         stmt->status = OCI_STMT_PREPARED;
02058 
02059         size = stmt->prefetch_size ? stmt->prefetch_size : OCI_PREFETCH_SIZE;
02060         res  = (res && OCI_SetPrefetchSize(stmt, size));
02061                 
02062         size = stmt->fetch_size ? stmt->fetch_size : OCI_FETCH_SIZE;
02063         res  = (res && OCI_SetFetchSize(stmt, size));
02064     }
02065 
02066     OCI_RESULT(res);
02067 
02068     return res;
02069 }
02070 
02071 /* --------------------------------------------------------------------------------------------- *
02072  * OCI_Execute
02073  * --------------------------------------------------------------------------------------------- */
02074 
02075 boolean OCI_API OCI_Execute
02076 (
02077     OCI_Statement *stmt
02078 )
02079 {
02080     return OCI_ExecuteInternal(stmt, OCI_DEFAULT);
02081 }
02082 
02083 /* --------------------------------------------------------------------------------------------- *
02084  * OCI_ExecuteStmt
02085  * --------------------------------------------------------------------------------------------- */
02086 
02087 boolean OCI_API OCI_ExecuteStmt
02088 (
02089     OCI_Statement *stmt,
02090     const mtext   *sql
02091 )
02092 {
02093     return (OCI_Prepare(stmt, sql) && OCI_ExecuteInternal(stmt, OCI_DEFAULT));
02094 }
02095 
02096 /* --------------------------------------------------------------------------------------------- *
02097  * OCI_Parse
02098  * --------------------------------------------------------------------------------------------- */
02099 
02100 boolean OCI_API OCI_Parse
02101 (
02102     OCI_Statement *stmt,
02103     const mtext   *sql
02104 )
02105 {
02106     return (OCI_Prepare(stmt, sql) && OCI_ExecuteInternal(stmt, OCI_PARSE_ONLY));
02107 }
02108 
02109 /* --------------------------------------------------------------------------------------------- *
02110  * OCI_Describe
02111  * --------------------------------------------------------------------------------------------- */
02112 
02113 boolean OCI_API OCI_Describe
02114 (
02115     OCI_Statement *stmt,
02116     const mtext   *sql
02117 )
02118 {
02119     boolean res = TRUE;
02120 
02121     res = OCI_Prepare(stmt, sql);
02122     
02123     if ((res == TRUE) && (stmt->type == OCI_CST_SELECT))
02124     {
02125         res = OCI_ExecuteInternal(stmt, OCI_DESCRIBE_ONLY);
02126     }
02127 
02128     return res;
02129 }
02130 
02131 /* --------------------------------------------------------------------------------------------- *
02132  * OCI_PrepareFmt
02133  * --------------------------------------------------------------------------------------------- */
02134 
02135 boolean OCI_PrepareFmt
02136 (
02137     OCI_Statement *stmt,
02138     const mtext   *sql,
02139     ...
02140 )
02141 {
02142     boolean res = FALSE;
02143     va_list args;
02144     int     size;
02145 
02146     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02147     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02148 
02149     /* first, get buffer size */
02150 
02151     va_start(args, sql);
02152 
02153     size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
02154 
02155     va_end(args);
02156 
02157     if (size > 0)
02158     {
02159         /* allocate buffer */
02160 
02161         mtext *sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size_t) (size+1), TRUE);
02162 
02163         if (sql_fmt != NULL)
02164         {
02165             /* format buffer */
02166 
02167             va_start(args, sql);
02168 
02169             if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
02170             {
02171                 /* parse buffer */
02172 
02173                 res = OCI_Prepare(stmt, sql_fmt);
02174             }
02175 
02176             va_end(args);
02177 
02178             OCI_FREE(sql_fmt);
02179         }
02180     }
02181 
02182     OCI_RESULT(res);
02183 
02184     return res;
02185 }
02186 
02187 /* --------------------------------------------------------------------------------------------- *
02188  * OCI_ExecuteStmtFmt
02189  * --------------------------------------------------------------------------------------------- */
02190 
02191 boolean OCI_ExecuteStmtFmt
02192 (
02193     OCI_Statement *stmt,
02194     const mtext   *sql,
02195     ...
02196 )
02197 {
02198     boolean res = FALSE;
02199     va_list args;
02200     int     size;
02201 
02202     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02203     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02204 
02205     /* first, get buffer size */
02206 
02207     va_start(args, sql);
02208 
02209     size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
02210 
02211     va_end(args);
02212 
02213     if (size > 0)
02214     {
02215         /* allocate buffer */
02216 
02217         mtext *sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size_t) (size+1), TRUE);
02218 
02219         if (sql_fmt != NULL)
02220         {
02221             /* format buffer */
02222 
02223             va_start(args, sql);
02224 
02225             if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
02226             {
02227                 /* prepare and execute SQL buffer */
02228 
02229                 res = (OCI_Prepare(stmt, sql_fmt) && OCI_ExecuteInternal(stmt, OCI_DEFAULT));
02230             }
02231 
02232             va_end(args);
02233 
02234             OCI_FREE(sql_fmt);
02235         }
02236     }
02237 
02238     OCI_RESULT(res);
02239 
02240     return res;
02241 }
02242 
02243 /* --------------------------------------------------------------------------------------------- *
02244  * OCI_ParseFmt
02245  * --------------------------------------------------------------------------------------------- */
02246 
02247 boolean OCI_ParseFmt
02248 (
02249     OCI_Statement *stmt,
02250     const mtext   *sql,
02251     ...
02252 )
02253 {
02254     boolean res     = FALSE;
02255     int     size    = 0;
02256     va_list args;
02257 
02258     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02259     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02260 
02261     /* first, get buffer size */
02262 
02263     va_start(args, sql);
02264 
02265     size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
02266 
02267     va_end(args);
02268 
02269     if (size > 0)
02270     {       
02271         /* allocate buffer */
02272 
02273         mtext  *sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size_t) (size+1), TRUE);
02274 
02275         if (sql_fmt != NULL)
02276         {
02277             /* format buffer */
02278 
02279             va_start(args, sql);
02280 
02281             if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
02282             {
02283                 /* prepare and execute SQL buffer */
02284 
02285                 res = (OCI_Prepare(stmt, sql_fmt) && OCI_ExecuteInternal(stmt, OCI_PARSE_ONLY));
02286             }
02287 
02288             va_end(args);
02289 
02290             OCI_FREE(sql_fmt);
02291         }
02292     }
02293 
02294     OCI_RESULT(res);
02295 
02296     return res;
02297 }
02298 
02299 /* --------------------------------------------------------------------------------------------- *
02300  * OCI_DescribeFmt
02301  * --------------------------------------------------------------------------------------------- */
02302 
02303 boolean OCI_DescribeFmt
02304 (
02305     OCI_Statement *stmt,
02306     const mtext   *sql,
02307     ...
02308 )
02309 {
02310     boolean res     = FALSE;
02311     int     size    = 0;
02312     va_list args;
02313 
02314     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02315     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02316 
02317     /* first, get buffer size */
02318 
02319     va_start(args, sql);
02320 
02321     size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
02322 
02323     va_end(args);
02324 
02325     if (size > 0)
02326     {
02327         /* allocate buffer */
02328 
02329         mtext  *sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size_t) (size+1), TRUE);
02330 
02331         if (sql_fmt != NULL)
02332         {
02333             /* format buffer */
02334 
02335             va_start(args, sql);
02336 
02337             if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
02338             {
02339                 /* prepare and execute SQL buffer */
02340 
02341                 res = (OCI_Prepare(stmt, sql_fmt) && OCI_ExecuteInternal(stmt, OCI_DESCRIBE_ONLY));
02342             }
02343 
02344             va_end(args);
02345 
02346             OCI_FREE(sql_fmt);
02347         }
02348     }
02349 
02350     OCI_RESULT(res);
02351 
02352     return res;
02353 }
02354 
02355 /* --------------------------------------------------------------------------------------------- *
02356  * OCI_Immediate
02357  * --------------------------------------------------------------------------------------------- */
02358 
02359 boolean OCI_Immediate
02360 (
02361     OCI_Connection *con,
02362     const mtext    *sql,
02363     ...
02364 )
02365 {
02366     OCI_Statement *stmt = NULL;
02367     boolean res         = FALSE;
02368     va_list args;
02369 
02370     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
02371     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02372 
02373     /* First, execute SQL */
02374 
02375     stmt = OCI_StatementCreate(con);
02376 
02377     if (stmt != NULL)
02378     {
02379         res = OCI_ExecuteStmt(stmt, sql);
02380 
02381         if (res == TRUE)
02382         {
02383             /* get resultset and set up variables */
02384 
02385             if (OCI_GetStatementType(stmt) == OCI_CST_SELECT)
02386             {
02387                 va_start(args, sql);
02388 
02389                 res = OCI_FetchIntoUserVariables(stmt, args);
02390 
02391                 va_end(args);
02392             }
02393         }
02394 
02395         OCI_StatementFree(stmt);
02396     }
02397 
02398     OCI_RESULT(res);
02399 
02400     return res;
02401 }
02402 
02403 /* --------------------------------------------------------------------------------------------- *
02404  * OCI_ImmediateFmt
02405  * --------------------------------------------------------------------------------------------- */
02406 
02407 boolean OCI_ImmediateFmt
02408 (
02409     OCI_Connection *con,
02410     const mtext    *sql,
02411     ...
02412 )
02413 {
02414     boolean         res     = FALSE;
02415     OCI_Statement  *stmt    = NULL;
02416 
02417     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
02418     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02419 
02420     stmt = OCI_StatementCreate(con);
02421 
02422     if (stmt != NULL)
02423     {
02424         int     size = 0;
02425         va_list args;
02426   
02427         /* first, get buffer size */
02428 
02429         va_start(args, sql);
02430 
02431         size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
02432 
02433         va_end(args);
02434 
02435         if (size > 0)
02436         {
02437             /* allocate buffer */
02438 
02439             mtext  *sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size_t) (size+1), TRUE);
02440 
02441             if (sql_fmt != NULL)
02442             {
02443                 /* format buffer */
02444 
02445                 va_start(args, sql);
02446 
02447                 if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
02448                 {
02449                     /* prepare and execute SQL buffer */
02450 
02451                     res = (OCI_Prepare(stmt, sql_fmt) && OCI_ExecuteInternal(stmt, OCI_DEFAULT));
02452 
02453                     /* get resultset and set up variables */
02454 
02455                     if (res && (OCI_GetStatementType(stmt) == OCI_CST_SELECT))
02456                     {
02457                         res = OCI_FetchIntoUserVariables(stmt, args);
02458                     }
02459                 }
02460 
02461                 va_end(args);
02462 
02463                 OCI_FREE(sql_fmt);
02464             }
02465         }
02466 
02467         OCI_StatementFree(stmt);
02468     }
02469 
02470     OCI_RESULT(res);
02471 
02472     return res;
02473 }
02474 
02475 /* --------------------------------------------------------------------------------------------- *
02476  * OCI_BindArraySetSize
02477  * --------------------------------------------------------------------------------------------- */
02478 
02479 boolean OCI_API OCI_BindArraySetSize
02480 (
02481     OCI_Statement *stmt,
02482     unsigned int   size
02483 )
02484 {
02485     boolean res = TRUE;
02486 
02487     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02488 
02489     OCI_CHECK_MIN(stmt->con, stmt, size, 1, FALSE);
02490 
02491     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_PREPARED, FALSE);
02492 
02493     /* if the statements already has binds, we need to check if the new size is
02494        not greater than the initial size
02495     */
02496 
02497     if ((stmt->nb_ubinds > 0) && (stmt->nb_iters_init < size))
02498     {
02499         OCI_ExceptionBindArraySize(stmt, stmt->nb_iters_init, stmt->nb_iters, size);
02500 
02501         res = FALSE;
02502     }
02503     else
02504     {
02505         stmt->nb_iters   = size;
02506         stmt->bind_array = TRUE;
02507 
02508         if (stmt->nb_ubinds == 0)
02509         {
02510             stmt->nb_iters_init = stmt->nb_iters;
02511         }
02512     }
02513 
02514     OCI_RESULT(res);
02515 
02516     return res;
02517 }
02518 
02519 /* --------------------------------------------------------------------------------------------- *
02520  * OCI_BindArrayGetSize
02521  * --------------------------------------------------------------------------------------------- */
02522 
02523 unsigned int OCI_API OCI_BindArrayGetSize
02524 (
02525     OCI_Statement *stmt
02526 )
02527 {
02528     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02529 
02530     OCI_RESULT(TRUE);
02531 
02532     return stmt->nb_iters;
02533 }
02534 
02535 /* --------------------------------------------------------------------------------------------- *
02536  * OCI_AllowRebinding
02537  * --------------------------------------------------------------------------------------------- */
02538 
02539 OCI_EXPORT boolean OCI_API OCI_AllowRebinding
02540 (
02541     OCI_Statement *stmt,
02542     boolean        value
02543 )
02544 {
02545     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02546 
02547     OCI_RESULT(TRUE);
02548 
02549     stmt->bind_reuse = value;
02550 
02551     return TRUE;
02552 }
02553 
02554 /* --------------------------------------------------------------------------------------------- *
02555  * OCI_BindShort
02556  * --------------------------------------------------------------------------------------------- */
02557 
02558 boolean OCI_API OCI_BindShort
02559 (
02560     OCI_Statement *stmt,
02561     const mtext   *name,
02562     short         *data
02563 )
02564 {
02565     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_SHORT);
02566 
02567     return OCI_BindData(stmt, data, sizeof(short), name, OCI_CDT_NUMERIC,
02568                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_SHORT, NULL, 0);
02569 }
02570 
02571 /* --------------------------------------------------------------------------------------------- *
02572  * OCI_BindArrayOfShorts
02573  * --------------------------------------------------------------------------------------------- */
02574 
02575 boolean OCI_API OCI_BindArrayOfShorts
02576 (
02577     OCI_Statement *stmt,
02578     const mtext   *name,
02579     short         *data,
02580     unsigned int   nbelem
02581 )
02582 {
02583     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_SHORT);
02584 
02585     return OCI_BindData(stmt, data, sizeof(short), name, OCI_CDT_NUMERIC,
02586                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_SHORT, NULL, nbelem);
02587 }
02588 
02589 /* --------------------------------------------------------------------------------------------- *
02590  * OCI_BindUnsignedShort
02591  * --------------------------------------------------------------------------------------------- */
02592 
02593 boolean OCI_API OCI_BindUnsignedShort
02594 (
02595     OCI_Statement  *stmt,
02596     const mtext    *name,
02597     unsigned short *data
02598 )
02599 {
02600     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_SHORT);
02601 
02602     return OCI_BindData(stmt, data, sizeof(unsigned short), name, OCI_CDT_NUMERIC,
02603                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_USHORT, NULL, 0);
02604 }
02605 
02606 /* --------------------------------------------------------------------------------------------- *
02607  * OCI_BindArrayOfUnsignedShorts
02608  * --------------------------------------------------------------------------------------------- */
02609 
02610 boolean OCI_API OCI_BindArrayOfUnsignedShorts
02611 (
02612     OCI_Statement  *stmt,
02613     const mtext    *name,
02614     unsigned short *data,
02615     unsigned int    nbelem
02616 )
02617 {
02618     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_SHORT);
02619 
02620     return OCI_BindData(stmt, data, sizeof(unsigned short), name, OCI_CDT_NUMERIC,
02621                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_USHORT, NULL, nbelem);
02622 }
02623 
02624 /* --------------------------------------------------------------------------------------------- *
02625  * OCI_BindInt
02626  * --------------------------------------------------------------------------------------------- */
02627 
02628 boolean OCI_API OCI_BindInt
02629 (
02630     OCI_Statement *stmt,
02631     const mtext   *name,
02632     int           *data
02633 )
02634 {
02635     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_INT);
02636 
02637     return OCI_BindData(stmt, data, sizeof(int), name, OCI_CDT_NUMERIC,
02638                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_INT, NULL, 0);
02639 }
02640 
02641 /* --------------------------------------------------------------------------------------------- *
02642  * OCI_BindArrayOfInts
02643  * --------------------------------------------------------------------------------------------- */
02644 
02645 boolean OCI_API OCI_BindArrayOfInts
02646 (
02647     OCI_Statement *stmt,
02648     const mtext   *name,
02649     int           *data,
02650     unsigned int   nbelem
02651 )
02652 {
02653     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_INT);
02654 
02655     return OCI_BindData(stmt, data, sizeof(int), name, OCI_CDT_NUMERIC,
02656                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_INT, NULL, nbelem);
02657 }
02658 
02659 /* --------------------------------------------------------------------------------------------- *
02660  * OCI_BindUnsignedInt
02661  * --------------------------------------------------------------------------------------------- */
02662 
02663 boolean OCI_API OCI_BindUnsignedInt
02664 (
02665     OCI_Statement *stmt,
02666     const mtext   *name,
02667     unsigned int  *data
02668 )
02669 {
02670     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_INT);
02671 
02672     return OCI_BindData(stmt, data, sizeof(unsigned int), name, OCI_CDT_NUMERIC,
02673                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_UINT, NULL, 0);
02674 }
02675 
02676 /* --------------------------------------------------------------------------------------------- *
02677  * OCI_BindArrayOfUnsignedInts
02678  * --------------------------------------------------------------------------------------------- */
02679 
02680 boolean OCI_API OCI_BindArrayOfUnsignedInts
02681 (
02682     OCI_Statement *stmt,
02683     const mtext   *name,
02684     unsigned int  *data,
02685     unsigned int   nbelem
02686 )
02687 {
02688     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_INT);
02689 
02690     return OCI_BindData(stmt, data, sizeof(unsigned int), name, OCI_CDT_NUMERIC,
02691                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_UINT, NULL, nbelem);
02692 }
02693 
02694 /* --------------------------------------------------------------------------------------------- *
02695  * OCI_BindBigInt
02696  * --------------------------------------------------------------------------------------------- */
02697 
02698 boolean OCI_API OCI_BindBigInt
02699 (
02700     OCI_Statement *stmt,
02701     const mtext   *name,
02702     big_int       *data
02703 )
02704 {
02705     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_BIGINT);
02706 
02707     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02708                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGINT, NULL, 0);
02709 }
02710 
02711 /* --------------------------------------------------------------------------------------------- *
02712  * OCI_BindArrayOfBigInts
02713  * --------------------------------------------------------------------------------------------- */
02714 
02715 boolean OCI_API OCI_BindArrayOfBigInts
02716 (
02717     OCI_Statement *stmt,
02718     const mtext   *name,
02719     big_int       *data,
02720     unsigned int   nbelem
02721 )
02722 {
02723     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_BIGINT);
02724 
02725     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02726                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGINT, NULL, nbelem);
02727 }
02728 
02729 /* --------------------------------------------------------------------------------------------- *
02730  * OCI_BindUnsignedBigInt
02731  * --------------------------------------------------------------------------------------------- */
02732 
02733 boolean OCI_API OCI_BindUnsignedBigInt
02734 (
02735     OCI_Statement *stmt,
02736     const mtext   *name,
02737     big_uint      *data
02738 )
02739 {
02740     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_BIGINT);
02741 
02742     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02743                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGUINT, NULL, 0);
02744 }
02745 
02746 /* --------------------------------------------------------------------------------------------- *
02747  * OCI_BindArrayOfUnsignedInts
02748  * --------------------------------------------------------------------------------------------- */
02749 
02750 boolean OCI_API OCI_BindArrayOfUnsignedBigInts
02751 (
02752     OCI_Statement *stmt,
02753     const mtext   *name,
02754     big_uint      *data,
02755     unsigned int   nbelem
02756 )
02757 {
02758     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_BIGINT);
02759 
02760     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02761                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGUINT, NULL, nbelem);
02762 }
02763 
02764 /* --------------------------------------------------------------------------------------------- *
02765  * OCI_BindString
02766  * --------------------------------------------------------------------------------------------- */
02767 
02768 boolean OCI_API OCI_BindString
02769 (
02770     OCI_Statement *stmt,
02771     const mtext   *name,
02772     dtext         *data,
02773     unsigned int   len
02774 )
02775 {
02776     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_STRING);
02777 
02778     if ((len == 0) || len == (UINT_MAX))
02779     {
02780         if (data != NULL)
02781         {
02782             /* only compute length for external bind if no valid length has been provided */
02783 
02784             len = (unsigned int) dtslen(data);
02785         }
02786         else
02787         {
02788             /* if data is NULL, it means that binding mode is OCI_BAM_INTERNAL.
02789                An invalid length passed to the function, we do not have a valid length to 
02790                allocate internal array, thus we need to raise an exception */
02791     
02792             OCI_ExceptionMinimumValue(stmt->con, stmt, 1);
02793 
02794             return FALSE;
02795         }
02796     }
02797 
02798 
02799     return OCI_BindData(stmt, data, (len + 1) * (ub4) sizeof(odtext), name,
02800                         OCI_CDT_TEXT, SQLT_STR, OCI_BIND_INPUT, 0, NULL, 0);
02801 }
02802 
02803 /* --------------------------------------------------------------------------------------------- *
02804  * OCI_BindArrayOfStrings
02805  * --------------------------------------------------------------------------------------------- */
02806 
02807 boolean OCI_API OCI_BindArrayOfStrings
02808 (
02809     OCI_Statement *stmt,
02810     const mtext   *name,
02811     dtext         *data,
02812     unsigned int   len,
02813     unsigned int   nbelem
02814 )
02815 {
02816     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_STRING);
02817 
02818     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02819 
02820     return OCI_BindData(stmt, data, (len + 1) * (ub4) sizeof(odtext), name,
02821                         OCI_CDT_TEXT, SQLT_STR, OCI_BIND_INPUT, 0, NULL, nbelem);
02822 }
02823 
02824 /* --------------------------------------------------------------------------------------------- *
02825  * OCI_BindRaw
02826  * --------------------------------------------------------------------------------------------- */
02827 
02828 boolean OCI_API OCI_BindRaw
02829 (
02830     OCI_Statement *stmt,
02831     const mtext   *name,
02832     void          *data,
02833     unsigned int   len
02834 )
02835 {
02836     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_VOID);
02837 
02838     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02839 
02840     return OCI_BindData(stmt, data, len, name, OCI_CDT_RAW,
02841                         SQLT_BIN, OCI_BIND_INPUT, 0, NULL, 0);
02842 }
02843 
02844 /* --------------------------------------------------------------------------------------------- *
02845  * OCI_BindArrayOfRaws
02846  * --------------------------------------------------------------------------------------------- */
02847 
02848 boolean OCI_API OCI_BindArrayOfRaws
02849 (
02850     OCI_Statement *stmt,
02851     const mtext   *name,
02852     void          *data,
02853     unsigned int   len,
02854     unsigned int   nbelem
02855 )
02856 {
02857     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_VOID);
02858 
02859     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02860 
02861     return OCI_BindData(stmt, data, len, name, OCI_CDT_RAW,
02862                         SQLT_BIN, OCI_BIND_INPUT, 0, NULL, nbelem);
02863 }
02864 
02865 /* --------------------------------------------------------------------------------------------- *
02866  * OCI_BindDouble
02867  * --------------------------------------------------------------------------------------------- */
02868 
02869 boolean OCI_API OCI_BindDouble
02870 (
02871     OCI_Statement *stmt,
02872     const mtext   *name,
02873     double        *data
02874 )
02875 {
02876     int code = SQLT_FLT;
02877 
02878     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_DOUBLE);
02879 
02880 #if OCI_VERSION_COMPILE >= OCI_10_1
02881 
02882     if (OCILib.version_runtime >= OCI_10_1)
02883     {
02884         code = SQLT_BDOUBLE;
02885     }
02886 
02887 #endif
02888 
02889     return OCI_BindData(stmt, data, sizeof(double), name, OCI_CDT_NUMERIC,
02890                         code, OCI_BIND_INPUT, OCI_NUM_DOUBLE, NULL, 0);
02891 }
02892 
02893 /* --------------------------------------------------------------------------------------------- *
02894  * OCI_BindArrayOfDoubles
02895  * --------------------------------------------------------------------------------------------- */
02896 
02897 boolean OCI_API OCI_BindArrayOfDoubles
02898 (
02899     OCI_Statement *stmt,
02900     const mtext   *name,
02901     double        *data,
02902     unsigned int   nbelem
02903 )
02904 {
02905     int code = SQLT_FLT;
02906 
02907     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_DOUBLE);
02908 
02909 #if OCI_VERSION_COMPILE >= OCI_10_1
02910 
02911     if (OCILib.version_runtime >= OCI_10_1)
02912     {
02913         code = SQLT_BDOUBLE;
02914     }
02915 
02916 #endif
02917 
02918     return OCI_BindData(stmt, data, sizeof(double), name, OCI_CDT_NUMERIC,
02919                         code, OCI_BIND_INPUT, OCI_NUM_DOUBLE, NULL, nbelem);
02920 }
02921 
02922 /* --------------------------------------------------------------------------------------------- *
02923  * OCI_BindFloat
02924  * --------------------------------------------------------------------------------------------- */
02925 
02926 boolean OCI_API OCI_BindFloat
02927 (
02928     OCI_Statement *stmt,
02929     const mtext   *name,
02930     float         *data
02931 )
02932 {
02933     int code = SQLT_FLT;
02934 
02935     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_FLOAT);
02936 
02937 #if OCI_VERSION_COMPILE >= OCI_10_1
02938 
02939     if (OCILib.version_runtime >= OCI_10_1)
02940     {
02941         code = SQLT_BFLOAT;
02942     }
02943 
02944 #endif
02945 
02946     return OCI_BindData(stmt, data, sizeof(float), name, OCI_CDT_NUMERIC,
02947                         code, OCI_BIND_INPUT, OCI_NUM_FLOAT, NULL, 0);
02948 }
02949 
02950 /* --------------------------------------------------------------------------------------------- *
02951  * OCI_BindArrayOfFloats
02952  * --------------------------------------------------------------------------------------------- */
02953 
02954 boolean OCI_API OCI_BindArrayOfFloats
02955 (
02956     OCI_Statement *stmt,
02957     const mtext   *name,
02958     float         *data,
02959     unsigned int   nbelem
02960 )
02961 {
02962     int code = SQLT_FLT;
02963 
02964     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_FLOAT);
02965 
02966 #if OCI_VERSION_COMPILE >= OCI_10_1
02967 
02968     if (OCILib.version_runtime >= OCI_10_1)
02969     {
02970         code = SQLT_BFLOAT;
02971     }
02972 
02973 #endif
02974 
02975     return OCI_BindData(stmt, data, sizeof(float), name, OCI_CDT_NUMERIC,
02976                         code, OCI_BIND_INPUT, OCI_NUM_FLOAT, NULL, nbelem);
02977 }
02978 
02979 /* --------------------------------------------------------------------------------------------- *
02980  * OCI_BindDate
02981  * --------------------------------------------------------------------------------------------- */
02982 
02983 boolean OCI_API OCI_BindDate
02984 (
02985     OCI_Statement *stmt,
02986     const mtext   *name,
02987     OCI_Date      *data
02988 )
02989 {
02990     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_DATE);
02991 
02992     return OCI_BindData(stmt, data, sizeof(OCIDate), name, OCI_CDT_DATETIME,
02993                         SQLT_ODT, OCI_BIND_INPUT, 0, NULL, 0);
02994 }
02995 
02996 /* --------------------------------------------------------------------------------------------- *
02997  * OCI_BindArrayOfDates
02998  * --------------------------------------------------------------------------------------------- */
02999 
03000 boolean OCI_API OCI_BindArrayOfDates
03001 (
03002     OCI_Statement *stmt,
03003     const mtext   *name,
03004     OCI_Date     **data,
03005     unsigned int   nbelem
03006 )
03007 {
03008     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_DATE);
03009 
03010     return OCI_BindData(stmt, data, sizeof(OCIDate), name, OCI_CDT_DATETIME,
03011                         SQLT_ODT, OCI_BIND_INPUT, 0, NULL, nbelem);
03012 }
03013 
03014 /* --------------------------------------------------------------------------------------------- *
03015  * OCI_BindTimestamp
03016  * --------------------------------------------------------------------------------------------- */
03017 
03018 boolean OCI_API OCI_BindTimestamp
03019 (
03020     OCI_Statement *stmt,
03021     const mtext   *name,
03022     OCI_Timestamp *data
03023 )
03024 {
03025     int code    = 0;
03026     boolean res = FALSE;
03027 
03028     OCI_CHECK_BIND_CALL1(stmt, name, data, OCI_IPC_TIMESTAMP);
03029 
03030     OCI_CHECK_TIMESTAMP_ENABLED(stmt->con, FALSE);
03031 
03032 #if OCI_VERSION_COMPILE >= OCI_9_0
03033 
03034     /* map oracle internal type */
03035 
03036     if (data->type == OCI_TIMESTAMP_TZ)
03037     {
03038         code = SQLT_TIMESTAMP_TZ;
03039     }
03040     else if (data->type == OCI_TIMESTAMP_LTZ)
03041     {
03042         code = SQLT_TIMESTAMP_LTZ;
03043     }
03044     else
03045     {
03046         code = SQLT_TIMESTAMP;
03047     }
03048 
03049     res = OCI_BindData(stmt, data, sizeof(OCIDateTime *), name, OCI_CDT_TIMESTAMP,
03050                        code, OCI_BIND_INPUT, data->type, NULL, 0);
03051 
03052 #else
03053 
03054     OCI_NOT_USED(name);
03055     OCI_NOT_USED(code);
03056     OCI_NOT_USED(code);
03057 
03058 #endif
03059 
03060     return res;
03061 }
03062 
03063 /* --------------------------------------------------------------------------------------------- *
03064  * OCI_BindArrayOfTimestamps
03065  * --------------------------------------------------------------------------------------------- */
03066 
03067 boolean OCI_API OCI_BindArrayOfTimestamps
03068 (
03069     OCI_Statement  *stmt,
03070     const mtext    *name,
03071     OCI_Timestamp **data,
03072     unsigned int    type,
03073     unsigned int    nbelem
03074 )
03075 {
03076     unsigned int code = 0;
03077     boolean res       = FALSE;
03078 
03079     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_TIMESTAMP);
03080 
03081     OCI_CHECK_TIMESTAMP_ENABLED(stmt->con, FALSE);
03082 
03083 #if OCI_VERSION_COMPILE >= OCI_9_0
03084 
03085     /* map oracle internal type */
03086 
03087     if (type == OCI_TIMESTAMP_TZ)
03088     {    
03089         code = SQLT_TIMESTAMP_TZ;
03090     }
03091     else if (type == OCI_TIMESTAMP_LTZ)
03092     {    
03093         code = SQLT_TIMESTAMP_LTZ;
03094     }
03095     else
03096     {    
03097         code = SQLT_TIMESTAMP;
03098     }
03099 
03100     res =  OCI_BindData(stmt, data, sizeof(OCIDateTime *), name, OCI_CDT_TIMESTAMP,
03101                         code, OCI_BIND_INPUT, type, NULL, nbelem);
03102 
03103 #else
03104 
03105     OCI_NOT_USED(name);
03106     OCI_NOT_USED(type);
03107     OCI_NOT_USED(code);
03108     OCI_NOT_USED(nbelem);
03109 
03110 #endif
03111 
03112     return res;
03113 }
03114 
03115 /* --------------------------------------------------------------------------------------------- *
03116  * OCI_BindInterval
03117  * --------------------------------------------------------------------------------------------- */
03118 
03119 boolean OCI_API OCI_BindInterval
03120 (
03121     OCI_Statement *stmt,
03122     const mtext   *name,
03123     OCI_Interval  *data
03124 )
03125 {
03126     int code    = 0;
03127     boolean res = FALSE;
03128 
03129     OCI_CHECK_BIND_CALL1(stmt, name, data, OCI_IPC_INTERVAL);
03130 
03131     OCI_CHECK_INTERVAL_ENABLED(stmt->con, FALSE);
03132 
03133 #if OCI_VERSION_COMPILE >= OCI_9_0
03134 
03135     /* map oracle internal type */
03136 
03137     if (data->type == OCI_INTERVAL_YM)
03138     {
03139         code = SQLT_INTERVAL_YM;
03140     }
03141     else if (data->type == OCI_INTERVAL_DS)
03142     {
03143         code = SQLT_INTERVAL_DS;
03144     }
03145 
03146     res = OCI_BindData(stmt, data, sizeof(OCIInterval *), name, OCI_CDT_INTERVAL,
03147                        code, OCI_BIND_INPUT, data->type, NULL, 0);
03148 
03149 #else
03150 
03151     OCI_NOT_USED(name);
03152     OCI_NOT_USED(code);
03153 
03154 #endif
03155 
03156     return res;
03157 }
03158 
03159 /* --------------------------------------------------------------------------------------------- *
03160  * OCI_BindArrayOfIntervals
03161  * --------------------------------------------------------------------------------------------- */
03162 
03163 boolean OCI_API OCI_BindArrayOfIntervals
03164 (
03165     OCI_Statement *stmt,
03166     const mtext   *name,
03167     OCI_Interval **data,
03168     unsigned int   type,
03169     unsigned int   nbelem
03170 )
03171 {
03172     unsigned int code = 0;
03173     boolean res       = FALSE;
03174 
03175     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_INTERVAL);
03176 
03177     OCI_CHECK_INTERVAL_ENABLED(stmt->con, FALSE);
03178 
03179 #if OCI_VERSION_COMPILE >= OCI_9_0
03180 
03181     /* map oracle internal type */
03182 
03183     if (type == OCI_INTERVAL_YM)
03184     {
03185         code = SQLT_INTERVAL_YM;
03186     }
03187     else if (type == OCI_INTERVAL_DS)
03188     {
03189         code = SQLT_INTERVAL_DS;
03190     }
03191 
03192     res = OCI_BindData(stmt, data, sizeof(OCIInterval *), name, OCI_CDT_INTERVAL,
03193                        code, OCI_BIND_INPUT, type, NULL, nbelem);
03194 
03195 #else
03196 
03197     OCI_NOT_USED(name);
03198     OCI_NOT_USED(type);
03199     OCI_NOT_USED(code);
03200     OCI_NOT_USED(nbelem);
03201 
03202 #endif
03203 
03204     return res;
03205 }
03206 
03207 /* --------------------------------------------------------------------------------------------- *
03208  * OCI_BindObject
03209  * --------------------------------------------------------------------------------------------- */
03210 
03211 boolean OCI_API OCI_BindObject
03212 (
03213     OCI_Statement *stmt,
03214     const mtext   *name,
03215     OCI_Object    *data
03216 )
03217 {
03218     OCI_CHECK_BIND_CALL1(stmt, name, data, OCI_IPC_OBJECT);
03219 
03220     return OCI_BindData(stmt, data, sizeof(void*), name, OCI_CDT_OBJECT,
03221                         SQLT_NTY, OCI_BIND_INPUT, 0, data->typinf, 0);
03222 }
03223 
03224 /* --------------------------------------------------------------------------------------------- *
03225  * OCI_BindArrayOfObjects
03226  * --------------------------------------------------------------------------------------------- */
03227 
03228 boolean OCI_API OCI_BindArrayOfObjects
03229 (
03230     OCI_Statement *stmt,
03231     const mtext   *name,
03232     OCI_Object   **data,
03233     OCI_TypeInfo  *typinf,
03234     unsigned int   nbelem
03235 )
03236 {
03237     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_OBJECT);
03238 
03239     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
03240 
03241     return OCI_BindData(stmt, data, sizeof(void *), name, OCI_CDT_OBJECT,
03242                         SQLT_NTY, OCI_BIND_INPUT, 0, typinf, nbelem);
03243 }
03244 
03245 /* --------------------------------------------------------------------------------------------- *
03246  * OCI_BindLob
03247  * --------------------------------------------------------------------------------------------- */
03248 
03249 boolean OCI_API OCI_BindLob
03250 (
03251     OCI_Statement *stmt,
03252     const mtext   *name,
03253     OCI_Lob       *data
03254 )
03255 {
03256     int code = 0;
03257 
03258     OCI_CHECK_BIND_CALL1(stmt, name, data, OCI_IPC_LOB);
03259 
03260     /* map oracle internal type */
03261 
03262     if (data->type == OCI_CLOB || data->type == OCI_NCLOB)
03263     {
03264         code = SQLT_CLOB;
03265     }
03266     else
03267     {
03268         code = SQLT_BLOB;
03269     }
03270 
03271     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_LOB,
03272                         code, OCI_BIND_INPUT, data->type, NULL, 0);
03273 }
03274 
03275 /* --------------------------------------------------------------------------------------------- *
03276  * OCI_BindArrayOfLobs
03277  * --------------------------------------------------------------------------------------------- */
03278 
03279 boolean OCI_API OCI_BindArrayOfLobs
03280 (
03281     OCI_Statement *stmt,
03282     const mtext   *name,
03283     OCI_Lob      **data,
03284     unsigned int   type,
03285     unsigned int   nbelem
03286 )
03287 {
03288     unsigned int code = 0;
03289 
03290     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_LOB);
03291 
03292     /* map oracle internal type */
03293 
03294     if (type == OCI_CLOB || type == OCI_NCLOB)
03295     {
03296         code = SQLT_CLOB;
03297     }
03298     else
03299     {
03300         code = SQLT_BLOB;
03301     }
03302 
03303     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_LOB,
03304                         code, OCI_BIND_INPUT, type, NULL, nbelem);
03305 }
03306 
03307 /* --------------------------------------------------------------------------------------------- *
03308  * OCI_BindFile
03309  * --------------------------------------------------------------------------------------------- */
03310 
03311 boolean OCI_API OCI_BindFile
03312 (
03313     OCI_Statement *stmt,
03314     const mtext   *name,
03315     OCI_File      *data
03316 )
03317 {
03318     int code = 0;
03319 
03320     OCI_CHECK_BIND_CALL1(stmt, name, data, OCI_IPC_FILE);
03321 
03322     /* map oracle internal type */
03323 
03324     if (data->type == OCI_CFILE)
03325     {
03326         code = SQLT_CFILE;
03327     }
03328     else
03329     {
03330         code = SQLT_BFILE;
03331     }
03332 
03333     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_FILE,
03334                         code, OCI_BIND_INPUT, data->type, NULL, 0);
03335 }
03336 
03337 /* --------------------------------------------------------------------------------------------- *
03338  * OCI_BindArrayOfFiles
03339  * --------------------------------------------------------------------------------------------- */
03340 
03341 boolean OCI_API OCI_BindArrayOfFiles
03342 (
03343     OCI_Statement *stmt,
03344     const mtext   *name,
03345     OCI_File     **data,
03346     unsigned int   type,
03347     unsigned int   nbelem
03348 )
03349 {
03350     unsigned int code = 0;
03351 
03352     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_FILE);
03353 
03354     /* map oracle internal type */
03355 
03356     if (type == OCI_CFILE)
03357     {
03358         code = SQLT_CFILE;
03359     }
03360     else
03361     {
03362         code = SQLT_BFILE;
03363     }
03364 
03365     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_FILE,
03366                         code, OCI_BIND_INPUT, type, NULL, nbelem);
03367 }
03368 
03369 /* --------------------------------------------------------------------------------------------- *
03370  * OCI_BindRef
03371  * --------------------------------------------------------------------------------------------- */
03372 
03373 boolean OCI_API OCI_BindRef
03374 (
03375     OCI_Statement *stmt,
03376     const mtext   *name,
03377     OCI_Ref       *data
03378 )
03379 {
03380     OCI_CHECK_BIND_CALL1(stmt, name, data, OCI_IPC_REF);
03381 
03382     return OCI_BindData(stmt, data, sizeof(OCIRef *), name, OCI_CDT_REF,
03383                         SQLT_REF, OCI_BIND_INPUT, 0, data->typinf, 0);
03384 }
03385 
03386 /* --------------------------------------------------------------------------------------------- *
03387  * OCI_BindArrayOfRefs
03388  * --------------------------------------------------------------------------------------------- */
03389 
03390 boolean OCI_API OCI_BindArrayOfRefs
03391 (
03392     OCI_Statement *stmt,
03393     const mtext   *name,
03394     OCI_Ref      **data,
03395     OCI_TypeInfo  *typinf,
03396     unsigned int   nbelem
03397 )
03398 {
03399     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_REF);
03400 
03401     return OCI_BindData(stmt, data, sizeof(OCIRef *), name, OCI_CDT_REF,
03402                         SQLT_REF, OCI_BIND_INPUT, 0, typinf, nbelem);
03403 }
03404 
03405 /* --------------------------------------------------------------------------------------------- *
03406  * OCI_BindColl
03407  * --------------------------------------------------------------------------------------------- */
03408 
03409 boolean OCI_API OCI_BindColl
03410 (
03411     OCI_Statement *stmt,
03412     const mtext   *name,
03413     OCI_Coll      *data
03414 )
03415 {
03416     OCI_CHECK_BIND_CALL1(stmt, name, data, OCI_IPC_COLLECTION);
03417 
03418     return OCI_BindData(stmt, data, sizeof(OCIColl*), name, OCI_CDT_COLLECTION, SQLT_NTY,
03419                         OCI_BIND_INPUT, 0, data->typinf, 0);
03420 }
03421 
03422 /* --------------------------------------------------------------------------------------------- *
03423  * OCI_BindArrayOfColls
03424  * --------------------------------------------------------------------------------------------- */
03425 
03426 boolean OCI_API OCI_BindArrayOfColls
03427 (
03428     OCI_Statement *stmt,
03429     const mtext   *name,
03430     OCI_Coll     **data,
03431     OCI_TypeInfo  *typinf,
03432     unsigned int   nbelem
03433 )
03434 {
03435     OCI_CHECK_BIND_CALL2(stmt, name, data, OCI_IPC_COLLECTION);
03436 
03437     return OCI_BindData(stmt, data, sizeof(OCIColl*), name, OCI_CDT_COLLECTION, SQLT_NTY, 
03438                         OCI_BIND_INPUT, 0, typinf, nbelem);
03439 }
03440 
03441 /* --------------------------------------------------------------------------------------------- *
03442  * OCI_BindStatement
03443  * --------------------------------------------------------------------------------------------- */
03444 
03445 boolean OCI_API OCI_BindStatement
03446 (
03447     OCI_Statement *stmt,
03448     const mtext   *name,
03449     OCI_Statement *data
03450 )
03451 {
03452     boolean res = FALSE;
03453 
03454     OCI_CHECK_BIND_CALL1(stmt, name, data, OCI_IPC_STATEMENT);
03455 
03456     res = OCI_BindData(stmt, &data->stmt, sizeof(OCIStmt*), name, OCI_CDT_CURSOR,
03457                        SQLT_RSET, OCI_BIND_INPUT, 0, NULL, 0);
03458 
03459     return res;
03460 }
03461 
03462 /* --------------------------------------------------------------------------------------------- *
03463  * OCI_BindLong
03464  * --------------------------------------------------------------------------------------------- */
03465 
03466 boolean OCI_API OCI_BindLong
03467 (
03468     OCI_Statement *stmt,
03469     const mtext   *name,
03470     OCI_Long      *data,
03471     unsigned int   size
03472 )
03473 {
03474     int code = 0;
03475 
03476     OCI_CHECK_BIND_CALL1(stmt, name, data, OCI_IPC_LONG);
03477 
03478     /* map oracle internal type */
03479 
03480     if (data->type == OCI_CLONG)
03481     {
03482         code = SQLT_LNG;
03483     }
03484     else
03485     {
03486         code = SQLT_LBI;
03487     }
03488 
03489     if (data->type == OCI_CLONG)
03490     {
03491         size *= (unsigned int) sizeof(dtext);
03492     }
03493 
03494     return OCI_BindData(stmt, data, size, name, OCI_CDT_LONG,
03495                         code, OCI_BIND_INPUT, data->type, NULL, 0);
03496 }
03497 
03498 /* --------------------------------------------------------------------------------------------- *
03499  * OCI_RegisterShort
03500  * --------------------------------------------------------------------------------------------- */
03501 
03502 boolean OCI_API OCI_RegisterShort
03503 (
03504     OCI_Statement *stmt,
03505     const mtext   *name
03506 )
03507 {
03508     OCI_CHECK_REGISTER_CALL(stmt, name);
03509 
03510     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03511                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_SHORT, NULL, 0);
03512 }
03513 
03514 /* --------------------------------------------------------------------------------------------- *
03515  * OCI_RegisterUnsignedShort
03516  * --------------------------------------------------------------------------------------------- */
03517 
03518 boolean OCI_API OCI_RegisterUnsignedShort
03519 (
03520     OCI_Statement *stmt,
03521     const mtext   *name
03522 )
03523 {
03524     OCI_CHECK_REGISTER_CALL(stmt, name);
03525 
03526     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03527                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_USHORT, NULL, 0);
03528 }
03529 
03530 /* --------------------------------------------------------------------------------------------- *
03531  * OCI_RegisterInt
03532  * --------------------------------------------------------------------------------------------- */
03533 
03534 boolean OCI_API OCI_RegisterInt
03535 (
03536     OCI_Statement *stmt,
03537     const mtext   *name
03538 )
03539 {
03540     OCI_CHECK_REGISTER_CALL(stmt, name);
03541 
03542     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03543                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_INT, NULL, 0);
03544 }
03545 
03546 /* --------------------------------------------------------------------------------------------- *
03547  * OCI_RegisterUnsignedInt
03548  * --------------------------------------------------------------------------------------------- */
03549 
03550 boolean OCI_API OCI_RegisterUnsignedInt
03551 (
03552     OCI_Statement *stmt,
03553     const mtext   *name
03554 )
03555 {
03556     OCI_CHECK_REGISTER_CALL(stmt, name);
03557 
03558     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03559                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_UINT, NULL, 0);
03560 }
03561 
03562 /* --------------------------------------------------------------------------------------------- *
03563  * OCI_RegisterBigInt
03564  * --------------------------------------------------------------------------------------------- */
03565 
03566 boolean OCI_API OCI_RegisterBigInt
03567 (
03568     OCI_Statement *stmt,
03569     const mtext   *name
03570 )
03571 {
03572     OCI_CHECK_REGISTER_CALL(stmt, name);
03573 
03574     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03575                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_BIGINT, NULL, 0);
03576 }
03577 
03578 /* --------------------------------------------------------------------------------------------- *
03579  * OCI_RegisterUnsignedBigInt
03580  * --------------------------------------------------------------------------------------------- */
03581 
03582 boolean OCI_API OCI_RegisterUnsignedBigInt
03583 (
03584     OCI_Statement *stmt,
03585     const mtext   *name
03586 )
03587 {
03588     OCI_CHECK_REGISTER_CALL(stmt, name);
03589 
03590     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03591                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_BIGUINT, NULL, 0);
03592 }
03593 
03594 /* --------------------------------------------------------------------------------------------- *
03595  * OCI_RegisterString
03596  * --------------------------------------------------------------------------------------------- */
03597 
03598 boolean OCI_API OCI_RegisterString
03599 (
03600     OCI_Statement *stmt,
03601     const mtext   *name,
03602     unsigned int   len
03603 )
03604 {
03605     OCI_CHECK_REGISTER_CALL(stmt, name);
03606 
03607     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
03608 
03609     return OCI_BindData(stmt, NULL, (len + 1) * (ub4) sizeof(odtext), name,
03610                         OCI_CDT_TEXT, SQLT_STR, OCI_BIND_OUTPUT, 0, NULL, 0);
03611 }
03612 
03613 /* --------------------------------------------------------------------------------------------- *
03614  * OCI_RegisterRaw
03615  * --------------------------------------------------------------------------------------------- */
03616 
03617 boolean OCI_API OCI_RegisterRaw
03618 (
03619     OCI_Statement *stmt,
03620     const mtext   *name,
03621     unsigned int   len
03622 )
03623 {
03624     OCI_CHECK_REGISTER_CALL(stmt, name);
03625 
03626     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
03627 
03628     return OCI_BindData(stmt, NULL, len, name, OCI_CDT_RAW,
03629                         SQLT_BIN, OCI_BIND_OUTPUT, 0, NULL, 0);
03630 }
03631 
03632 /* --------------------------------------------------------------------------------------------- *
03633  * OCI_RegisterDouble
03634  * --------------------------------------------------------------------------------------------- */
03635 
03636 boolean OCI_API OCI_RegisterDouble
03637 (
03638     OCI_Statement *stmt,
03639     const mtext   *name
03640 )
03641 {
03642     OCI_CHECK_REGISTER_CALL(stmt, name);
03643 
03644     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03645                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_DOUBLE, NULL, 0);
03646 }
03647 
03648 /* --------------------------------------------------------------------------------------------- *
03649  * OCI_RegisterFloat
03650  * --------------------------------------------------------------------------------------------- */
03651 
03652 boolean OCI_API OCI_RegisterFloat
03653 (
03654     OCI_Statement *stmt,
03655     const mtext   *name
03656 )
03657 {
03658     OCI_CHECK_REGISTER_CALL(stmt, name);
03659 
03660     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03661                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_FLOAT, NULL, 0);
03662 }
03663 
03664 /* --------------------------------------------------------------------------------------------- *
03665  * OCI_RegisterDate
03666  * --------------------------------------------------------------------------------------------- */
03667 
03668 boolean OCI_API OCI_RegisterDate
03669 (
03670     OCI_Statement *stmt,
03671     const mtext   *name
03672 )
03673 {
03674     int code = SQLT_ODT;
03675     int size = sizeof(OCIDate);
03676 
03677     OCI_CHECK_REGISTER_CALL(stmt, name);
03678 
03679     /* versions of OCI (< 10.2) crashes if SQLT_ODT is passed for output
03680        data with returning clause.
03681        It's an Oracle known bug #3269146 */
03682 
03683     if (OCI_GetVersionConnection(stmt->con) < OCI_10_2)
03684     {
03685         code = SQLT_DAT;
03686         size = 7;
03687     }
03688 
03689     return OCI_BindData(stmt, NULL, size, name, OCI_CDT_DATETIME,
03690                         code, OCI_BIND_OUTPUT, 0, NULL, 0);
03691 }
03692 
03693 /* --------------------------------------------------------------------------------------------- *
03694  * OCI_RegisterTimestamp
03695  * --------------------------------------------------------------------------------------------- */
03696 
03697 boolean OCI_API OCI_RegisterTimestamp
03698 (
03699     OCI_Statement *stmt,
03700     const mtext   *name,
03701     unsigned int   type
03702 )
03703 {
03704     int code    = 0;
03705     boolean res = FALSE;
03706 
03707     OCI_CHECK_REGISTER_CALL(stmt, name);
03708 
03709     OCI_CHECK_TIMESTAMP_ENABLED(stmt->con, FALSE);
03710 
03711 #if OCI_VERSION_COMPILE >= OCI_9_0
03712 
03713     /* map oracle internal type */
03714 
03715     if (type == OCI_TIMESTAMP_TZ)
03716     {
03717         code = SQLT_TIMESTAMP_TZ;
03718     }
03719     else if (type == OCI_TIMESTAMP_LTZ)
03720     {
03721         code = SQLT_TIMESTAMP_LTZ;
03722     }
03723     else
03724     {
03725         code = SQLT_TIMESTAMP;
03726     }
03727 
03728     res = OCI_BindData(stmt, NULL, sizeof(OCIDateTime *), name, OCI_CDT_TIMESTAMP,
03729                        code, OCI_BIND_OUTPUT, type, NULL, 0);
03730 
03731 #else
03732 
03733     OCI_NOT_USED(name);
03734     OCI_NOT_USED(type);
03735     OCI_NOT_USED(code);
03736 
03737 #endif
03738 
03739     return res;
03740 }
03741 
03742 /* --------------------------------------------------------------------------------------------- *
03743  * OCI_RegisterInterval
03744  * --------------------------------------------------------------------------------------------- */
03745 
03746 boolean OCI_API OCI_RegisterInterval
03747 (
03748     OCI_Statement *stmt,
03749     const mtext   *name,
03750     unsigned int   type
03751 )
03752 {
03753     unsigned int code = 0;
03754     boolean res       = FALSE;
03755 
03756     OCI_CHECK_REGISTER_CALL(stmt, name);
03757 
03758     OCI_CHECK_INTERVAL_ENABLED(stmt->con, FALSE);
03759 
03760 #if OCI_VERSION_COMPILE >= OCI_9_0
03761 
03762     /* map oracle internal type */
03763 
03764     if (type == OCI_INTERVAL_YM)
03765     {
03766         code = SQLT_INTERVAL_YM;
03767     }
03768     else if (type == OCI_INTERVAL_DS)
03769     {
03770         code = SQLT_INTERVAL_DS;
03771     }
03772     
03773     res = OCI_BindData(stmt, NULL, sizeof(OCIInterval *), name, OCI_CDT_INTERVAL,
03774                        code, OCI_BIND_OUTPUT, type, NULL, 0);
03775 
03776 #else
03777 
03778     OCI_NOT_USED(name);
03779     OCI_NOT_USED(type);
03780     OCI_NOT_USED(code);
03781 
03782 #endif
03783 
03784     return res;
03785 }
03786 
03787 /* --------------------------------------------------------------------------------------------- *
03788  * OCI_RegisterObject
03789  * --------------------------------------------------------------------------------------------- */
03790 
03791 boolean OCI_API OCI_RegisterObject
03792 (
03793     OCI_Statement *stmt,
03794     const mtext   *name,
03795     OCI_TypeInfo  *typinf
03796 )
03797 {
03798     OCI_CHECK_REGISTER_CALL(stmt, name);
03799 
03800     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
03801 
03802     return OCI_BindData(stmt, NULL, sizeof(OCIInterval *), name, OCI_CDT_OBJECT,
03803                         SQLT_NTY, OCI_BIND_OUTPUT, 0, typinf, 0);
03804 }
03805 
03806 /* --------------------------------------------------------------------------------------------- *
03807  * OCI_RegisterLob
03808  * --------------------------------------------------------------------------------------------- */
03809 
03810 boolean OCI_API OCI_RegisterLob
03811 (
03812     OCI_Statement *stmt,
03813     const mtext   *name,
03814     unsigned int   type
03815 )
03816 {
03817     unsigned int code = 0;
03818 
03819     OCI_CHECK_REGISTER_CALL(stmt, name);
03820 
03821     /* map oracle internal type */
03822 
03823     if (type == OCI_CLOB || type == OCI_NCLOB)
03824     {
03825         code = SQLT_CLOB;
03826     }
03827     else
03828     {
03829         code = SQLT_BLOB;
03830     }
03831 
03832     return OCI_BindData(stmt, NULL, sizeof(OCILobLocator*), name, OCI_CDT_LOB,
03833                         code, OCI_BIND_OUTPUT, type, NULL, 0);
03834 }
03835 
03836 /* --------------------------------------------------------------------------------------------- *
03837  * OCI_RegisterFile
03838  * --------------------------------------------------------------------------------------------- */
03839 
03840 boolean OCI_API OCI_RegisterFile
03841 (
03842     OCI_Statement *stmt,
03843     const mtext   *name,
03844     unsigned int   type
03845 )
03846 {
03847     unsigned int code;
03848 
03849     OCI_CHECK_REGISTER_CALL(stmt, name);
03850 
03851     /* map oracle internal type */
03852 
03853     if (type == OCI_CFILE)
03854     {
03855         code = SQLT_CFILE;
03856     }
03857     else
03858     {
03859         code = SQLT_BFILE;
03860     }
03861 
03862     return OCI_BindData(stmt, NULL, sizeof(OCILobLocator*), name, OCI_CDT_FILE,
03863                         code, OCI_BIND_OUTPUT, type, NULL, 0);
03864 }
03865 
03866 /* --------------------------------------------------------------------------------------------- *
03867  * OCI_RegisterRef
03868  * --------------------------------------------------------------------------------------------- */
03869 
03870 boolean OCI_API OCI_RegisterRef
03871 (
03872     OCI_Statement *stmt,
03873     const mtext   *name,
03874     OCI_TypeInfo  *typinf
03875 )
03876 {
03877     OCI_CHECK_REGISTER_CALL(stmt, name);
03878 
03879     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
03880 
03881     return OCI_BindData(stmt, NULL, sizeof(OCIRef *), name, OCI_CDT_REF,
03882                         SQLT_REF, OCI_BIND_OUTPUT, 0, typinf, 0);
03883 }
03884 
03885 /* --------------------------------------------------------------------------------------------- *
03886  * OCI_GetStatementType
03887  * --------------------------------------------------------------------------------------------- */
03888 
03889 unsigned int OCI_API OCI_GetStatementType
03890 (
03891     OCI_Statement *stmt
03892 )
03893 {
03894     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
03895 
03896     OCI_RESULT(TRUE);
03897 
03898     return stmt->type;
03899 }
03900 
03901 /* --------------------------------------------------------------------------------------------- *
03902  * OCI_SetFetchMode
03903  * --------------------------------------------------------------------------------------------- */
03904 
03905 boolean OCI_API OCI_SetFetchMode
03906 (
03907     OCI_Statement *stmt,
03908     unsigned int   mode
03909 )
03910 {
03911     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
03912 
03913     OCI_CHECK_SCROLLABLE_CURSOR_ENABLED(stmt->con, FALSE);
03914 
03915     stmt->exec_mode = mode;
03916 
03917     OCI_RESULT(TRUE);
03918 
03919     return TRUE;
03920 }
03921 
03922 /* --------------------------------------------------------------------------------------------- *
03923  * OCI_GetFetchMode
03924  * --------------------------------------------------------------------------------------------- */
03925 
03926 unsigned int OCI_API OCI_GetFetchMode
03927 (
03928     OCI_Statement *stmt
03929 )
03930 {
03931     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
03932 
03933     OCI_CHECK_SCROLLABLE_CURSOR_ENABLED(stmt->con, OCI_UNKNOWN);
03934 
03935     OCI_RESULT(TRUE);
03936 
03937     return stmt->exec_mode;
03938 }
03939 
03940 /* --------------------------------------------------------------------------------------------- *
03941  * OCI_SetBindMode
03942  * --------------------------------------------------------------------------------------------- */
03943 
03944 boolean OCI_API OCI_SetBindMode
03945 (
03946     OCI_Statement *stmt,
03947     unsigned int   mode
03948 )
03949 {
03950     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
03951 
03952     stmt->bind_mode = mode;
03953 
03954     OCI_RESULT(TRUE);
03955 
03956     return TRUE;
03957 }
03958 
03959 /* --------------------------------------------------------------------------------------------- *
03960  * OCI_GetBindMode
03961  * --------------------------------------------------------------------------------------------- */
03962 
03963 unsigned int OCI_API OCI_GetBindMode
03964 (
03965     OCI_Statement *stmt
03966 )
03967 {
03968     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
03969 
03970     OCI_RESULT(TRUE);
03971 
03972     return stmt->bind_mode;
03973 }
03974 
03975 /* --------------------------------------------------------------------------------------------- *
03976  * OCI_SetBindAllocation
03977  * --------------------------------------------------------------------------------------------- */
03978 
03979 boolean OCI_API OCI_SetBindAllocation
03980 (
03981     OCI_Statement *stmt,
03982     unsigned int   mode
03983 )
03984 {
03985     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
03986 
03987     stmt->bind_alloc_mode = mode;
03988 
03989     OCI_RESULT(TRUE);
03990 
03991     return TRUE;
03992 }
03993 
03994 /* --------------------------------------------------------------------------------------------- *
03995  * OCI_GetBindAllocation
03996  * --------------------------------------------------------------------------------------------- */
03997 
03998 unsigned int OCI_API OCI_GetBindAllocation
03999 (
04000     OCI_Statement *stmt
04001 )
04002 {
04003     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
04004 
04005     OCI_RESULT(TRUE);
04006 
04007     return stmt->bind_alloc_mode;
04008 }
04009 
04010 /* --------------------------------------------------------------------------------------------- *
04011  * OCI_SetFetchSize
04012  * --------------------------------------------------------------------------------------------- */
04013 
04014 boolean OCI_API OCI_SetFetchSize
04015 (
04016     OCI_Statement *stmt,
04017     unsigned int   size
04018 )
04019 {
04020     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
04021 
04022     OCI_CHECK_MIN(stmt->con, stmt, size, 1, FALSE);
04023 
04024     stmt->fetch_size = size;
04025 
04026     OCI_RESULT(TRUE);
04027 
04028     return TRUE;
04029 }
04030 
04031 /* --------------------------------------------------------------------------------------------- *
04032  * OCI_GetFetchSize
04033  * --------------------------------------------------------------------------------------------- */
04034 
04035 unsigned int OCI_API OCI_GetFetchSize
04036 (
04037     OCI_Statement *stmt
04038 )
04039 {
04040     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04041 
04042     OCI_RESULT(TRUE);
04043 
04044     return stmt->fetch_size;
04045 }
04046 
04047 /* --------------------------------------------------------------------------------------------- *
04048  * OCI_SetPrefetchSize
04049  * --------------------------------------------------------------------------------------------- */
04050 
04051 boolean OCI_API OCI_SetPrefetchSize
04052 (
04053     OCI_Statement *stmt,
04054     unsigned int   size
04055 )
04056 {
04057     boolean res = TRUE;
04058 
04059     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  FALSE);
04060   
04061     stmt->prefetch_size = size;
04062     
04063     if (stmt->stmt != NULL)
04064     {
04065         OCI_CALL1
04066         (
04067             res, stmt->con, stmt,
04068 
04069             OCIAttrSet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
04070                        (dvoid *) &stmt->prefetch_size,
04071                        (ub4) sizeof(stmt->prefetch_size),
04072                        (ub4) OCI_ATTR_PREFETCH_ROWS, stmt->con->err)
04073         )
04074     }
04075 
04076     OCI_RESULT(res);
04077 
04078     return res;
04079 }
04080 
04081 /* --------------------------------------------------------------------------------------------- *
04082  * OCI_GetPrefetchSize
04083  * --------------------------------------------------------------------------------------------- */
04084 
04085 unsigned int OCI_API OCI_GetPrefetchSize
04086 (
04087     OCI_Statement *stmt
04088 )
04089 {
04090     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04091 
04092     OCI_RESULT(TRUE);
04093 
04094     return stmt->prefetch_size;
04095 }
04096 
04097 /* --------------------------------------------------------------------------------------------- *
04098  * OCI_SetPrefetchMemory
04099  * --------------------------------------------------------------------------------------------- */
04100 
04101 boolean OCI_API OCI_SetPrefetchMemory
04102 (
04103     OCI_Statement *stmt,
04104     unsigned int   size
04105 )
04106 {
04107     boolean res = TRUE;
04108 
04109     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  FALSE);
04110 
04111     stmt->prefetch_mem = size;
04112 
04113     if (stmt->stmt != NULL)
04114     {
04115         OCI_CALL1
04116         (
04117             res, stmt->con, stmt,
04118 
04119             OCIAttrSet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
04120                        (dvoid *) &stmt->prefetch_mem,
04121                        (ub4) sizeof(stmt->prefetch_mem),
04122                        (ub4) OCI_ATTR_PREFETCH_MEMORY, stmt->con->err)
04123         )
04124     }
04125 
04126     OCI_RESULT(res);
04127 
04128     return res;
04129 }
04130 
04131 /* --------------------------------------------------------------------------------------------- *
04132  * OCI_GetPrefetchMemory
04133  * --------------------------------------------------------------------------------------------- */
04134 
04135 unsigned int OCI_API OCI_GetPrefetchMemory
04136 (
04137     OCI_Statement *stmt
04138 )
04139 {
04140     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04141 
04142     OCI_RESULT(TRUE);
04143 
04144     return stmt->prefetch_mem;
04145 }
04146 
04147 /* --------------------------------------------------------------------------------------------- *
04148  * OCI_SetLongMaxSize
04149  * --------------------------------------------------------------------------------------------- */
04150 
04151 boolean OCI_API OCI_SetLongMaxSize
04152 (
04153     OCI_Statement *stmt,
04154     unsigned int   size
04155 )
04156 {
04157     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  FALSE);
04158 
04159     OCI_CHECK_MIN(stmt->con, stmt, size, 1, FALSE);
04160 
04161     stmt->long_size = size;
04162 
04163     OCI_RESULT(TRUE);
04164 
04165     return TRUE;
04166 }
04167 
04168 /* --------------------------------------------------------------------------------------------- *
04169  * OCI_GetLongMaxSize
04170  * --------------------------------------------------------------------------------------------- */
04171 
04172 unsigned int OCI_API OCI_GetLongMaxSize
04173 (
04174     OCI_Statement *stmt
04175 )
04176 {
04177     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04178 
04179     OCI_RESULT(TRUE);
04180 
04181     return stmt->long_size;
04182 }
04183 
04184 /* --------------------------------------------------------------------------------------------- *
04185  * OCI_SetLongMode
04186  * --------------------------------------------------------------------------------------------- */
04187 
04188 boolean OCI_API OCI_SetLongMode
04189 (
04190     OCI_Statement *stmt,
04191     unsigned int   mode
04192 )
04193 {
04194     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
04195 
04196     stmt->long_mode = (ub1) mode;
04197 
04198     OCI_RESULT(TRUE);
04199 
04200     return TRUE;
04201 }
04202 
04203 /* --------------------------------------------------------------------------------------------- *
04204  * OCI_GetLongMode
04205  * --------------------------------------------------------------------------------------------- */
04206 
04207 unsigned int OCI_API OCI_GetLongMode
04208 (
04209     OCI_Statement *stmt
04210 )
04211 {
04212     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
04213 
04214     OCI_RESULT(TRUE);
04215 
04216     return stmt->long_mode;
04217 }
04218 
04219 /* --------------------------------------------------------------------------------------------- *
04220  * OCI_StatementGetConnection
04221  * --------------------------------------------------------------------------------------------- */
04222 
04223 OCI_Connection * OCI_API OCI_StatementGetConnection
04224 (
04225     OCI_Statement *stmt
04226 )
04227 {
04228     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
04229 
04230     OCI_RESULT(TRUE);
04231 
04232     return stmt->con;
04233 }
04234 
04235 /* --------------------------------------------------------------------------------------------- *
04236  * OCI_GetSql
04237  * --------------------------------------------------------------------------------------------- */
04238 
04239 const mtext * OCI_API OCI_GetSql
04240 (
04241     OCI_Statement *stmt
04242 )
04243 {
04244     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
04245 
04246     OCI_RESULT(TRUE);
04247 
04248     return stmt->sql;
04249 }
04250 
04251 /* --------------------------------------------------------------------------------------------- *
04252  * OCI_GetSqlErrorPos
04253  * --------------------------------------------------------------------------------------------- */
04254 
04255 unsigned int OCI_API OCI_GetSqlErrorPos
04256 (
04257     OCI_Statement *stmt
04258 )
04259 {
04260     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04261 
04262     OCI_RESULT(TRUE);
04263 
04264     return stmt->err_pos;
04265 }
04266 
04267 /* --------------------------------------------------------------------------------------------- *
04268  * OCI_GetAffecteddRows
04269  * --------------------------------------------------------------------------------------------- */
04270 
04271 unsigned int OCI_API OCI_GetAffectedRows
04272 (
04273     OCI_Statement *stmt
04274 )
04275 {
04276     boolean res = TRUE;
04277     ub4 count   = 0;
04278 
04279     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  0);
04280     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_EXECUTED, 0);
04281 
04282     OCI_CALL1
04283     (
04284         res, stmt->con, stmt,
04285 
04286         OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
04287                    (void *) &count, (ub4 *) NULL, (ub4) OCI_ATTR_ROW_COUNT,
04288                    stmt->con->err)
04289     )
04290 
04291     OCI_RESULT(res);
04292 
04293     return count;
04294 }
04295 
04296 /* --------------------------------------------------------------------------------------------- *
04297  * OCI_GetBindCount
04298  * --------------------------------------------------------------------------------------------- */
04299 
04300 unsigned int OCI_API OCI_GetBindCount
04301 (
04302     OCI_Statement *stmt
04303 )
04304 {
04305     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04306 
04307     OCI_RESULT(TRUE);
04308 
04309     return (unsigned int) stmt->nb_ubinds;
04310 }
04311 
04312 /* --------------------------------------------------------------------------------------------- *
04313  * OCI_GetBind
04314  * --------------------------------------------------------------------------------------------- */
04315 
04316 OCI_Bind * OCI_API OCI_GetBind
04317 (
04318     OCI_Statement *stmt,
04319     unsigned int   index
04320 )
04321 {
04322     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
04323     OCI_CHECK_BOUND(stmt->con, index, 1, stmt->nb_ubinds, NULL);
04324 
04325     OCI_RESULT(TRUE);
04326 
04327     return stmt->ubinds[index-1];
04328 }
04329 
04330 /* --------------------------------------------------------------------------------------------- *
04331  * OCI_GetBind2
04332  * --------------------------------------------------------------------------------------------- */
04333 
04334 OCI_Bind * OCI_API OCI_GetBind2
04335 (
04336     OCI_Statement *stmt,
04337     const mtext   *name
04338 )
04339 {
04340     OCI_Bind *bnd = NULL;
04341     int index     = -1;
04342 
04343     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
04344     OCI_CHECK_PTR(OCI_IPC_STRING, name, NULL);
04345 
04346     index =  OCI_BindGetIndex(stmt, name);
04347 
04348     if (index > 0)
04349     {
04350         bnd = stmt->ubinds[index-1];
04351     }
04352 
04353     OCI_RESULT(bnd != NULL);
04354 
04355     return bnd;
04356 }
04357 
04358 /* --------------------------------------------------------------------------------------------- *
04359  * OCI_GetSQLCommand
04360  * --------------------------------------------------------------------------------------------- */
04361 
04362 unsigned int OCI_API OCI_GetSQLCommand
04363 (
04364     OCI_Statement *stmt
04365 )
04366 {
04367     boolean res = TRUE;
04368     ub2 code    = OCI_UNKNOWN;
04369 
04370     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
04371     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_EXECUTED, OCI_UNKNOWN);
04372 
04373     OCI_CALL1
04374     (
04375         res, stmt->con, stmt,
04376 
04377         OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
04378                    (dvoid *) &code, (ub4 *) NULL,
04379                    (ub4) OCI_ATTR_SQLFNCODE, stmt->con->err)
04380     )
04381 
04382     OCI_RESULT(res);
04383 
04384     return (unsigned int) code;
04385 }
04386 
04387 /* --------------------------------------------------------------------------------------------- *
04388  * OCI_GetSQLVerb
04389  * --------------------------------------------------------------------------------------------- */
04390 
04391 const mtext * OCI_API OCI_GetSQLVerb
04392 (
04393     OCI_Statement *stmt
04394 )
04395 {
04396     mtext * desc      = NULL;
04397     unsigned int code = OCI_UNKNOWN;
04398 
04399     code = OCI_GetSQLCommand(stmt);
04400 
04401     if (code != OCI_UNKNOWN)
04402     {
04403         int i;
04404         
04405         for (i = 0; i < OCI_SQLCMD_COUNT; i++)
04406         {
04407             if (code == SQLCmds[i].code)
04408             {
04409                 desc = SQLCmds[i].verb;
04410                 break;
04411             }
04412         }
04413     }
04414 
04415     return desc;
04416 }
04417 
04418 /* --------------------------------------------------------------------------------------------- *
04419  * OCI_GetBatchError
04420  * --------------------------------------------------------------------------------------------- */
04421 
04422 OCI_Error * OCI_API OCI_GetBatchError
04423 (
04424     OCI_Statement *stmt
04425 )
04426 {
04427     OCI_Error *err = NULL;
04428 
04429     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
04430 
04431     if (stmt->batch != NULL)
04432     {
04433         if (stmt->batch->cur < stmt->batch->count)
04434         {
04435             err = &stmt->batch->errs[stmt->batch->cur++];
04436         }
04437     }
04438 
04439     OCI_RESULT(TRUE);
04440 
04441     return err;
04442 }
04443 
04444 /* --------------------------------------------------------------------------------------------- *
04445  * OCI_GetBatchErrorCount
04446  * --------------------------------------------------------------------------------------------- */
04447 
04448 unsigned int OCI_API OCI_GetBatchErrorCount
04449 (
04450     OCI_Statement *stmt
04451 )
04452 {
04453     unsigned int count = 0;
04454 
04455     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04456 
04457     if (stmt->batch != NULL)
04458     {
04459         count = stmt->batch->count;
04460     }
04461 
04462     OCI_RESULT(TRUE);
04463 
04464     return count;
04465 }
04466