OCILIB (C Driver for Oracle) 3.12.1
|
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: column.c, Vincent Rogier $ 00033 * --------------------------------------------------------------------------------------------- */ 00034 00035 #include "ocilib_internal.h" 00036 00037 /* ********************************************************************************************* * 00038 * PRIVATE FUNCTIONS 00039 * ********************************************************************************************* */ 00040 00041 /* --------------------------------------------------------------------------------------------- * 00042 * OCI_ColumnDescribe 00043 * --------------------------------------------------------------------------------------------- */ 00044 00045 boolean OCI_ColumnDescribe 00046 ( 00047 OCI_Column *col, 00048 OCI_Connection *con, 00049 OCI_Statement *stmt, 00050 void *handle, 00051 int index, 00052 int ptype 00053 ) 00054 { 00055 void *param = NULL; 00056 boolean res = TRUE; 00057 00058 /* get descriptor */ 00059 00060 if (ptype == OCI_DESC_COLLECTION) 00061 { 00062 OCI_CALL1 00063 ( 00064 res, con, stmt, 00065 00066 OCIAttrGet((dvoid *) handle, (ub4) OCI_DTYPE_PARAM, (dvoid *) ¶m, 00067 (ub4 *) NULL, (ub4) OCI_ATTR_COLLECTION_ELEMENT, con->err) 00068 ) 00069 } 00070 else 00071 { 00072 ub4 htype = 0; 00073 00074 if (ptype == OCI_DESC_RESULTSET) 00075 { 00076 htype = OCI_HTYPE_STMT; 00077 } 00078 else 00079 { 00080 htype = OCI_DTYPE_PARAM; 00081 } 00082 00083 OCI_CALL1 00084 ( 00085 res, con, stmt, 00086 00087 OCIParamGet((dvoid *) handle, htype, con->err, (void**) ¶m, (ub4) index) 00088 ) 00089 } 00090 00091 /* sql code */ 00092 00093 OCI_CALL1 00094 ( 00095 res, con, stmt, 00096 00097 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &col->ocode, 00098 (ub4 *) NULL, (ub4) OCI_ATTR_DATA_TYPE, con->err) 00099 ) 00100 00101 /* size */ 00102 00103 OCI_CALL1 00104 ( 00105 res, con, stmt, 00106 00107 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &col->size, 00108 (ub4 *) NULL, (ub4) OCI_ATTR_DATA_SIZE, con->err) 00109 ) 00110 00111 /* scale */ 00112 00113 OCI_CALL1 00114 ( 00115 res, con, stmt, 00116 00117 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &col->scale, 00118 (ub4 *) NULL, (ub4) OCI_ATTR_SCALE, con->err) 00119 ) 00120 00121 /* precision */ 00122 00123 if (ptype == OCI_DESC_RESULTSET) 00124 { 00125 sb2 prec = 0; 00126 00127 OCI_CALL1 00128 ( 00129 res, con, stmt, 00130 00131 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &prec, 00132 (ub4 *) NULL, (ub4) OCI_ATTR_PRECISION, con->err) 00133 ) 00134 00135 col->prec = (sb2) prec; 00136 } 00137 else 00138 { 00139 ub1 prec = 0; 00140 00141 OCI_CALL1 00142 ( 00143 res, con, stmt, 00144 00145 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &prec, 00146 (ub4 *) NULL, (ub4) OCI_ATTR_PRECISION, con->err) 00147 ) 00148 00149 col->prec = (sb2) prec; 00150 } 00151 00152 /* charset form */ 00153 00154 OCI_CALL1 00155 ( 00156 res, con, stmt, 00157 00158 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &col->csfrm, 00159 (ub4 *) NULL, (ub4) OCI_ATTR_CHARSET_FORM, con->err) 00160 ) 00161 00162 /* type of column length for string based column */ 00163 00164 #if OCI_VERSION_COMPILE >= OCI_9_2 00165 00166 if ((OCILib.version_runtime >= OCI_9_2) && (con->ver_num >= OCI_9_2)) 00167 { 00168 /* char used - no error checking because on Oracle 9.0, querying 00169 this param that is not char/varchar based will cause an 00170 error */ 00171 00172 OCI_CALL1 00173 ( 00174 res, con, stmt, 00175 00176 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, 00177 (dvoid *) &col->charused, (ub4 *) NULL, 00178 (ub4) OCI_ATTR_CHAR_USED, con->err) 00179 ) 00180 } 00181 00182 /* char size */ 00183 00184 if (col->charused == TRUE) 00185 { 00186 OCI_CALL1 00187 ( 00188 res, con, stmt, 00189 00190 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, 00191 (dvoid *) &col->charsize, (ub4 *) NULL, 00192 (ub4) OCI_ATTR_CHAR_SIZE, con->err) 00193 ) 00194 } 00195 00196 if ((OCILib.version_runtime >= OCI_9_0) && (con->ver_num >= OCI_9_0)) 00197 { 00198 /* fractional time precision for timestamps */ 00199 00200 if (col->ocode == SQLT_TIMESTAMP || 00201 col->ocode == SQLT_TIMESTAMP_TZ || 00202 col->ocode == SQLT_TIMESTAMP_LTZ) 00203 { 00204 OCI_CALL1 00205 ( 00206 res, con, stmt, 00207 00208 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, 00209 (dvoid *) &col->prec, (ub4 *) NULL, 00210 (ub4) OCI_ATTR_FSPRECISION, con->err) 00211 ) 00212 } 00213 00214 /* leading and fractional precision for interval */ 00215 00216 if (col->ocode == SQLT_INTERVAL_DS || col->ocode == SQLT_INTERVAL_YM) 00217 { 00218 OCI_CALL1 00219 ( 00220 res, con, stmt, 00221 00222 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, 00223 (dvoid *) &col->prec, (ub4 *) NULL, 00224 (ub4) OCI_ATTR_LFPRECISION, con->err) 00225 ) 00226 00227 OCI_CALL1 00228 ( 00229 res, con, stmt, 00230 00231 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, 00232 (dvoid *) &col->prec2, (ub4 *) NULL, 00233 (ub4) OCI_ATTR_FSPRECISION, con->err) 00234 ) 00235 } 00236 } 00237 00238 #endif 00239 00240 /* check nullable only for table based column */ 00241 00242 if (ptype < OCI_DESC_TYPE) 00243 { 00244 OCI_CALL1 00245 ( 00246 res, con, stmt, 00247 00248 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, 00249 (dvoid *) &col->null, (ub4 *) NULL, 00250 (ub4) OCI_ATTR_IS_NULL, con->err) 00251 ) 00252 } 00253 else 00254 { 00255 col->null = TRUE; 00256 } 00257 00258 /* name */ 00259 00260 if (res == TRUE) 00261 { 00262 void *ostr = NULL; 00263 int osize = 0; 00264 ub4 attrname = 0; 00265 00266 if (ptype == OCI_DESC_COLLECTION) 00267 { 00268 attrname = OCI_ATTR_TYPE_NAME; 00269 } 00270 else 00271 { 00272 attrname = OCI_ATTR_NAME; 00273 } 00274 00275 OCI_CALL1 00276 ( 00277 res, con, stmt, 00278 00279 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &ostr, 00280 (ub4 *) &osize, (ub4) attrname, con->err) 00281 ) 00282 00283 if ((res == TRUE) && (ostr != NULL)) 00284 { 00285 col->name = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), 00286 (size_t) ((osize / (int) sizeof(omtext)) + 1), TRUE); 00287 00288 if (col->name != NULL) 00289 { 00290 OCI_CopyString(ostr, col->name, &osize, sizeof(omtext), sizeof(mtext)); 00291 } 00292 else 00293 { 00294 res = FALSE; 00295 } 00296 } 00297 } 00298 00299 /* user type descriptor */ 00300 00301 if (col->ocode == SQLT_NTY || col->ocode == SQLT_REF) 00302 { 00303 void *ostr_name = NULL; 00304 void *ostr_schema = NULL; 00305 int osize_name = 0; 00306 int osize_schema = 0; 00307 00308 OCI_CALL1 00309 ( 00310 res, con, stmt, 00311 00312 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, 00313 (dvoid *) &ostr_name, (ub4 *) &osize_name, 00314 (ub4) OCI_ATTR_TYPE_NAME, con->err) 00315 ) 00316 00317 OCI_CALL1 00318 ( 00319 res, con, stmt, 00320 00321 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, 00322 (dvoid *) &ostr_schema, (ub4 *) &osize_schema, 00323 (ub4) OCI_ATTR_SCHEMA_NAME, con->err) 00324 ) 00325 00326 if (res == TRUE) 00327 { 00328 mtext type_name[(OCI_SIZE_OBJ_NAME * 2) + 2] = MT(""); 00329 00330 if ((ostr_schema != NULL) && (osize_schema > 0)) 00331 { 00332 OCI_CopyString(ostr_schema, type_name, &osize_schema, sizeof(omtext), sizeof(mtext)); 00333 00334 mtscat(type_name, MT(".")); 00335 } 00336 00337 OCI_CopyString(ostr_name, ((char *) type_name) + mtextsize(type_name), &osize_name, 00338 sizeof(omtext), sizeof(mtext)); 00339 00340 col->typinf = OCI_TypeInfoGet(con, type_name, OCI_TIF_TYPE); 00341 00342 res = (col->typinf != NULL); 00343 } 00344 } 00345 00346 if (param != NULL) 00347 { 00348 res = (OCI_SUCCESS == OCIDescriptorFree(param, OCI_DTYPE_PARAM)); 00349 } 00350 00351 return res; 00352 } 00353 00354 /* --------------------------------------------------------------------------------------------- * 00355 * OCI_ColumnMap 00356 * --------------------------------------------------------------------------------------------- */ 00357 00358 boolean OCI_ColumnMap 00359 ( 00360 OCI_Column *col, 00361 OCI_Statement *stmt 00362 ) 00363 { 00364 ub2 char_size = (ub2) ( (OCILib.nls_utf8 == TRUE) ? UTF8_BYTES_PER_CHAR : sizeof(dtext) ); 00365 00366 boolean res = TRUE; 00367 00368 OCI_CHECK(col == NULL, FALSE); 00369 00370 /* map Oracle SQL code to OCILIB types and setup of internal buffer size */ 00371 00372 col->icode = col->ocode; 00373 00374 switch (col->icode) 00375 { 00376 case SQLT_INT: 00377 { 00378 col->type = OCI_CDT_NUMERIC; 00379 00380 /* set bufsize only if it's not a "returning into" placeholder */ 00381 00382 if (col->bufsize == 0) 00383 { 00384 col->subtype = OCI_NUM_INT; 00385 col->bufsize = sizeof(int); 00386 } 00387 00388 break; 00389 } 00390 case SQLT_UIN: 00391 { 00392 col->type = OCI_CDT_NUMERIC; 00393 00394 /* set bufsize only if it's not a "returning into" placeholder */ 00395 00396 if (col->bufsize == 0) 00397 { 00398 col->subtype = OCI_NUM_UINT; 00399 col->bufsize = sizeof(unsigned int); 00400 } 00401 00402 break; 00403 } 00404 case SQLT_FLT: 00405 case SQLT_VNU: 00406 case SQLT_PDN: 00407 case SQLT_NUM: 00408 { 00409 col->type = OCI_CDT_NUMERIC; 00410 col->subtype = OCI_NUM_NUMBER; 00411 col->icode = SQLT_VNU; 00412 col->bufsize = sizeof(OCINumber); 00413 00414 break; 00415 } 00416 00417 #if OCI_VERSION_COMPILE >= OCI_10_1 00418 00419 case SQLT_BFLOAT: 00420 case SQLT_IBFLOAT: 00421 { 00422 col->type = OCI_CDT_NUMERIC; 00423 col->subtype = OCI_NUM_FLOAT; 00424 col->icode = SQLT_BFLOAT; 00425 col->bufsize = sizeof(float); 00426 00427 break; 00428 } 00429 00430 #endif 00431 00432 #if OCI_VERSION_COMPILE >= OCI_10_1 00433 00434 case SQLT_BDOUBLE: 00435 case SQLT_IBDOUBLE: 00436 { 00437 00438 col->type = OCI_CDT_NUMERIC; 00439 col->subtype = OCI_NUM_DOUBLE; 00440 col->icode = SQLT_BDOUBLE; 00441 col->bufsize = sizeof(double); 00442 00443 break; 00444 } 00445 00446 #endif 00447 00448 case SQLT_DAT: 00449 case SQLT_ODT: 00450 { 00451 col->type = OCI_CDT_DATETIME; 00452 00453 /* We map to SQLT_ODT only it the column is not part of a 00454 "returning into" clause (workaround for Oracle 00455 known bug #3269146 00456 */ 00457 00458 if (col->bufsize == 0) 00459 { 00460 col->icode = SQLT_ODT; 00461 col->bufsize = sizeof(OCIDate); 00462 } 00463 00464 break; 00465 } 00466 case SQLT_CUR: 00467 case SQLT_RSET: 00468 { 00469 col->type = OCI_CDT_CURSOR; 00470 col->bufsize = sizeof(OCIStmt *); 00471 col->dtype = OCI_HTYPE_STMT; 00472 00473 break; 00474 } 00475 case SQLT_RID: 00476 case SQLT_RDD: 00477 { 00478 col->icode = SQLT_STR; 00479 col->type = OCI_CDT_TEXT; 00480 00481 if ((col->ocode == SQLT_RDD) || (col->size > sizeof(OCIRowid *))) 00482 { 00483 /* For Oracle 7 ROWIDs and regular ROWID descriptors, the 00484 max size of the hex value is defined by the constant 00485 OCI_SIZE_ROWID 00486 */ 00487 00488 col->bufsize = (ub4) ((OCI_SIZE_ROWID + 1) * char_size); 00489 } 00490 else 00491 { 00492 /* For ROWID descriptor, if column size is bigger than the size 00493 of the descriptor, it means that an UROWID column and then 00494 the column size is the maximum size needed for representing 00495 its value as an hex string 00496 */ 00497 00498 col->bufsize = (ub4) ((col->size + 1) * char_size); 00499 } 00500 00501 break; 00502 } 00503 case SQLT_BIN: 00504 { 00505 /* adding one extra character space for string conversion */ 00506 00507 col->type = OCI_CDT_RAW; 00508 col->bufsize = (ub4) (col->size + (ub2) sizeof(dtext)); 00509 00510 break; 00511 } 00512 case SQLT_BLOB: 00513 { 00514 col->type = OCI_CDT_LOB; 00515 col->subtype = OCI_BLOB; 00516 col->dtype = OCI_DTYPE_LOB; 00517 col->bufsize = (ub4) sizeof(OCILobLocator *); 00518 00519 break; 00520 } 00521 case SQLT_CLOB: 00522 { 00523 col->type = OCI_CDT_LOB; 00524 col->dtype = OCI_DTYPE_LOB; 00525 col->bufsize = (ub4) sizeof(OCILobLocator *); 00526 00527 if (col->csfrm == SQLCS_NCHAR) 00528 { 00529 col->subtype = OCI_NCLOB; 00530 } 00531 else 00532 { 00533 col->subtype = OCI_CLOB; 00534 } 00535 00536 break; 00537 } 00538 case SQLT_BFILE: 00539 { 00540 col->type = OCI_CDT_FILE; 00541 col->subtype = OCI_BFILE; 00542 col->dtype = OCI_DTYPE_LOB; 00543 col->bufsize = (ub4) sizeof(OCILobLocator *); 00544 00545 break; 00546 } 00547 case SQLT_CFILE: 00548 { 00549 col->type = OCI_CDT_FILE; 00550 col->subtype = OCI_CFILE; 00551 col->bufsize = (ub4) sizeof(OCILobLocator *); 00552 col->dtype = OCI_DTYPE_LOB; 00553 00554 break; 00555 } 00556 case SQLT_LNG: 00557 case SQLT_LVC: 00558 case SQLT_LBI: 00559 case SQLT_LVB: 00560 case SQLT_VBI: 00561 { 00562 if ((col->icode == SQLT_LNG || col->icode == SQLT_LVC) && 00563 (stmt != NULL && stmt->long_mode == OCI_LONG_IMPLICIT)) 00564 { 00565 col->type = OCI_CDT_TEXT; 00566 col->subtype = OCI_CLONG; 00567 col->bufsize = (OCI_SIZE_LONG+1) * char_size; 00568 00569 } 00570 else 00571 { 00572 col->type = OCI_CDT_LONG; 00573 col->bufsize = INT_MAX; 00574 00575 if (col->icode == SQLT_LBI || 00576 col->icode == SQLT_LVB || 00577 col->icode == SQLT_VBI) 00578 { 00579 col->subtype = OCI_BLONG; 00580 } 00581 else 00582 { 00583 col->subtype = OCI_CLONG; 00584 } 00585 00586 } 00587 00588 break; 00589 } 00590 00591 #if OCI_VERSION_COMPILE >= OCI_9_0 00592 00593 case SQLT_TIMESTAMP: 00594 { 00595 col->type = OCI_CDT_TIMESTAMP; 00596 col->subtype = OCI_TIMESTAMP; 00597 col->dtype = OCI_DTYPE_TIMESTAMP; 00598 col->bufsize = (ub4) sizeof(OCIDateTime *); 00599 00600 break; 00601 } 00602 case SQLT_TIMESTAMP_TZ: 00603 { 00604 col->type = OCI_CDT_TIMESTAMP; 00605 col->subtype = OCI_TIMESTAMP_TZ; 00606 col->dtype = OCI_DTYPE_TIMESTAMP_TZ; 00607 col->bufsize = (ub4) sizeof(OCIDateTime *); 00608 00609 break; 00610 } 00611 case SQLT_TIMESTAMP_LTZ: 00612 { 00613 col->type = OCI_CDT_TIMESTAMP; 00614 col->subtype = OCI_TIMESTAMP_LTZ; 00615 col->dtype = OCI_DTYPE_TIMESTAMP_LTZ; 00616 col->bufsize = (ub4) sizeof(OCIDateTime *); 00617 00618 break; 00619 } 00620 case SQLT_INTERVAL_YM: 00621 { 00622 col->type = OCI_CDT_INTERVAL; 00623 col->subtype = OCI_INTERVAL_YM; 00624 col->dtype = OCI_DTYPE_INTERVAL_YM; 00625 col->bufsize = (ub4) sizeof(OCIInterval *); 00626 00627 break; 00628 } 00629 case SQLT_INTERVAL_DS: 00630 { 00631 col->type = OCI_CDT_INTERVAL; 00632 col->subtype = OCI_INTERVAL_DS; 00633 col->dtype = OCI_DTYPE_INTERVAL_DS; 00634 col->bufsize = (ub4) sizeof(OCIInterval *); 00635 00636 break; 00637 } 00638 00639 #endif 00640 00641 #if OCI_VERSION_COMPILE >= OCI_9_0 00642 00643 case SQLT_PNTY: 00644 00645 #endif 00646 00647 case SQLT_NTY: 00648 { 00649 col->icode = SQLT_NTY; 00650 col->bufsize = (ub4) sizeof(void *); 00651 00652 if (col->typinf->tcode == SQLT_NCO) 00653 { 00654 col->type = OCI_CDT_COLLECTION; 00655 } 00656 else 00657 { 00658 col->type = OCI_CDT_OBJECT; 00659 } 00660 00661 break; 00662 } 00663 case SQLT_REF: 00664 { 00665 col->icode = SQLT_REF; 00666 col->bufsize = (ub4) sizeof(OCIRef *); 00667 col->type = OCI_CDT_REF; 00668 00669 break; 00670 } 00671 case SQLT_CHR: 00672 case SQLT_STR: 00673 case SQLT_VCS: 00674 case SQLT_AFC: 00675 case SQLT_AVC: 00676 case SQLT_VST: 00677 case SQLT_LAB: 00678 case SQLT_OSL: 00679 case SQLT_SLS: 00680 default: 00681 { 00682 col->icode = SQLT_STR; 00683 col->type = OCI_CDT_TEXT; 00684 col->bufsize = (ub4) ((col->size + 1) * char_size); 00685 00686 break; 00687 } 00688 } 00689 00690 return res; 00691 } 00692 00693 /* ********************************************************************************************* * 00694 * PUBLIC FUNCTIONS 00695 * ********************************************************************************************* */ 00696 00697 /* --------------------------------------------------------------------------------------------- * 00698 * OCI_ColumnGetName 00699 * --------------------------------------------------------------------------------------------- */ 00700 00701 const mtext * OCI_API OCI_ColumnGetName 00702 ( 00703 OCI_Column *col 00704 ) 00705 { 00706 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, NULL); 00707 00708 return col->name; 00709 } 00710 00711 /* --------------------------------------------------------------------------------------------- * 00712 * OCI_ColumnGetType 00713 * --------------------------------------------------------------------------------------------- */ 00714 00715 unsigned int OCI_API OCI_ColumnGetType 00716 ( 00717 OCI_Column *col 00718 ) 00719 { 00720 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, OCI_UNKNOWN); 00721 00722 OCI_RESULT(TRUE); 00723 00724 return col->type; 00725 } 00726 00727 /* --------------------------------------------------------------------------------------------- * 00728 * OCI_ColumnGetCharsetForm 00729 * --------------------------------------------------------------------------------------------- */ 00730 00731 unsigned int OCI_API OCI_ColumnGetCharsetForm 00732 ( 00733 OCI_Column *col 00734 ) 00735 { 00736 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, OCI_CSF_NONE); 00737 00738 OCI_RESULT(TRUE); 00739 00740 if (col->csfrm == SQLCS_NCHAR) 00741 { 00742 return OCI_CSF_NATIONAL; 00743 } 00744 else if (col->csfrm == SQLCS_IMPLICIT) 00745 { 00746 return OCI_CSF_DEFAULT; 00747 } 00748 else 00749 { 00750 return OCI_CSF_NONE; 00751 } 00752 } 00753 00754 /* --------------------------------------------------------------------------------------------- * 00755 * OCI_ColumnGetSize 00756 * --------------------------------------------------------------------------------------------- */ 00757 00758 unsigned int OCI_API OCI_ColumnGetSize 00759 ( 00760 OCI_Column *col 00761 ) 00762 { 00763 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0); 00764 00765 OCI_RESULT(TRUE); 00766 00767 /* Oracle 9i introduced CHAR attribute on string columns to indicate the 00768 size of the column is not in bytes (default) but in chars 00769 OCI_ColumnDescribe() already managed the Oracle compatibly 00770 version, so if col->charsize is zero it means : 00771 - the column is not a string column 00772 - the size is not in char 00773 - client does not support the OCI_ATTR_CHAR_SIZE attribute */ 00774 00775 if (col->charused == TRUE && col->charsize > 0) 00776 { 00777 return col->charsize; 00778 } 00779 else 00780 { 00781 return col->size; 00782 } 00783 } 00784 00785 /* --------------------------------------------------------------------------------------------- * 00786 * OCI_ColumnGetScale 00787 * --------------------------------------------------------------------------------------------- */ 00788 00789 int OCI_API OCI_ColumnGetScale 00790 ( 00791 OCI_Column *col 00792 ) 00793 { 00794 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0); 00795 00796 OCI_RESULT(TRUE); 00797 00798 return (int) col->scale; 00799 } 00800 00801 /* --------------------------------------------------------------------------------------------- * 00802 * OCI_ColumnGetPrecision 00803 * --------------------------------------------------------------------------------------------- */ 00804 00805 int OCI_API OCI_ColumnGetPrecision 00806 ( 00807 OCI_Column *col 00808 ) 00809 { 00810 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0); 00811 00812 OCI_RESULT(TRUE); 00813 00814 if (col->type == OCI_CDT_NUMERIC) 00815 { 00816 return (int) col->prec; 00817 } 00818 else 00819 { 00820 return 0; 00821 } 00822 } 00823 00824 /* --------------------------------------------------------------------------------------------- * 00825 * OCI_ColumnGetFractionalPrecision 00826 * --------------------------------------------------------------------------------------------- */ 00827 00828 int OCI_API OCI_ColumnGetFractionalPrecision 00829 ( 00830 OCI_Column *col 00831 ) 00832 { 00833 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0); 00834 00835 OCI_RESULT(TRUE); 00836 00837 if (col->type == OCI_CDT_TIMESTAMP) 00838 { 00839 return (int) col->prec; 00840 } 00841 else if (col->type == OCI_CDT_INTERVAL) 00842 { 00843 return (int) col->prec2; 00844 } 00845 else 00846 { 00847 return 0; 00848 } 00849 } 00850 00851 /* --------------------------------------------------------------------------------------------- * 00852 * OCI_ColumnGetLeadingPrecision 00853 * --------------------------------------------------------------------------------------------- */ 00854 00855 int OCI_API OCI_ColumnGetLeadingPrecision 00856 ( 00857 OCI_Column *col 00858 ) 00859 { 00860 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0); 00861 00862 OCI_RESULT(TRUE); 00863 00864 if (col->type == OCI_CDT_INTERVAL) 00865 { 00866 return (int) col->prec; 00867 } 00868 else 00869 { 00870 return 0; 00871 } 00872 } 00873 00874 /* --------------------------------------------------------------------------------------------- * 00875 * OCI_ColumnGetNullable 00876 * --------------------------------------------------------------------------------------------- */ 00877 00878 boolean OCI_API OCI_ColumnGetNullable 00879 ( 00880 OCI_Column *col 00881 ) 00882 { 00883 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, FALSE); 00884 00885 OCI_RESULT(TRUE); 00886 00887 return (col->null == TRUE); 00888 } 00889 00890 /* --------------------------------------------------------------------------------------------- * 00891 * OCI_ColumnGetCharUsed 00892 * --------------------------------------------------------------------------------------------- */ 00893 00894 boolean OCI_API OCI_ColumnGetCharUsed 00895 ( 00896 OCI_Column *col 00897 ) 00898 { 00899 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, FALSE); 00900 00901 OCI_RESULT(TRUE); 00902 00903 return (boolean) col->charused; 00904 } 00905 00906 /* --------------------------------------------------------------------------------------------- * 00907 * OCI_ColumnGetSQLType 00908 * --------------------------------------------------------------------------------------------- */ 00909 00910 const mtext * OCI_API OCI_ColumnGetSQLType 00911 ( 00912 OCI_Column *col 00913 ) 00914 { 00915 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, NULL); 00916 00917 /* VARCHAR type will not be returned because Oracle does not make any 00918 difference with VARCHAR2. If a column is created with VARCHAR, it is 00919 internally created as VARCHAR2 00920 */ 00921 00922 OCI_RESULT(TRUE); 00923 00924 switch(col->ocode) 00925 { 00926 case SQLT_AFC: 00927 { 00928 if (col->csfrm == SQLCS_NCHAR) 00929 { 00930 return MT("NCHAR"); 00931 } 00932 else 00933 { 00934 return MT("CHAR"); 00935 } 00936 } 00937 case SQLT_AVC: 00938 case SQLT_STR: 00939 case SQLT_CHR: 00940 { 00941 if (col->csfrm == SQLCS_NCHAR) 00942 { 00943 return MT("NVARCHAR2"); 00944 } 00945 else 00946 { 00947 return MT("VARCHAR2"); 00948 } 00949 } 00950 case SQLT_NUM: 00951 { 00952 if (col->scale == -127 && col->prec > 0) 00953 { 00954 return MT("FLOAT"); 00955 } 00956 else 00957 { 00958 return MT("NUMBER"); 00959 } 00960 } 00961 case SQLT_INT: 00962 { 00963 return MT("INTEGER"); 00964 } 00965 case SQLT_FLT: 00966 { 00967 return MT("FLOAT"); 00968 } 00969 00970 #if OCI_VERSION_COMPILE >= OCI_10_1 00971 00972 case SQLT_BFLOAT: 00973 case SQLT_IBFLOAT: 00974 { 00975 return MT("BINARY FLOAT"); 00976 } 00977 case SQLT_BDOUBLE: 00978 case SQLT_IBDOUBLE: 00979 { 00980 return MT("BINARY DOUBLE"); 00981 } 00982 00983 #endif 00984 00985 case SQLT_LNG: 00986 { 00987 return MT("LONG"); 00988 } 00989 case SQLT_DAT: 00990 case SQLT_ODT: 00991 case SQLT_DATE: 00992 { 00993 return MT("DATE"); 00994 } 00995 case SQLT_RDD: 00996 case SQLT_RID: 00997 { 00998 return MT("ROWID"); 00999 } 01000 case SQLT_BIN: 01001 { 01002 return MT("RAW"); 01003 } 01004 case SQLT_LBI: 01005 { 01006 return MT("LONG RAW"); 01007 } 01008 case SQLT_RSET: 01009 { 01010 return MT("RESULTSET"); 01011 } 01012 case SQLT_CUR: 01013 { 01014 return MT("CURSOR"); 01015 } 01016 case SQLT_CLOB: 01017 { 01018 if (col->subtype == OCI_NCLOB) 01019 { 01020 return MT("NCLOB"); 01021 } 01022 else 01023 { 01024 return MT("CLOB"); 01025 } 01026 } 01027 case SQLT_BLOB: 01028 { 01029 return MT("BLOB"); 01030 } 01031 case SQLT_BFILE: 01032 { 01033 return MT("BINARY FILE LOB"); 01034 } 01035 case SQLT_CFILE: 01036 { 01037 return MT("CFILE"); 01038 } 01039 01040 #if OCI_VERSION_COMPILE >= OCI_9_0 01041 01042 case SQLT_TIMESTAMP: 01043 { 01044 return MT("TIMESTAMP"); 01045 } 01046 case SQLT_TIMESTAMP_TZ: 01047 { 01048 return MT("TIMESTAMP WITH TIME ZONE"); 01049 } 01050 case SQLT_TIMESTAMP_LTZ: 01051 { 01052 return MT("TIMESTAMP WITH LOCAL TIME ZONE"); 01053 } 01054 case SQLT_INTERVAL_YM: 01055 { 01056 return MT("INTERVAL YEAR TO MONTH"); 01057 } 01058 case SQLT_INTERVAL_DS: 01059 { 01060 return MT("INTERVAL DAY TO SECOND"); 01061 } 01062 01063 #endif 01064 01065 case SQLT_REF: 01066 { 01067 return MT("REF"); 01068 } 01069 01070 #if OCI_VERSION_COMPILE >= OCI_9_0 01071 01072 case SQLT_PNTY: 01073 01074 #endif 01075 01076 case SQLT_NTY: 01077 { 01078 if (col->typinf != NULL) 01079 { 01080 return col->typinf->name; 01081 } 01082 else 01083 { 01084 return MT("NAMED TYPE"); 01085 } 01086 } 01087 default: 01088 { 01089 /* unknown datatype ? Should not happen because all 01090 datatypes are supported */ 01091 01092 return MT("?"); 01093 } 01094 } 01095 } 01096 01097 /* --------------------------------------------------------------------------------------------- * 01098 * OCI_ColumnGetFullSQLType 01099 * --------------------------------------------------------------------------------------------- */ 01100 01101 unsigned int OCI_API OCI_ColumnGetFullSQLType 01102 ( 01103 OCI_Column *col, 01104 mtext *buffer, 01105 unsigned int len 01106 ) 01107 { 01108 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0); 01109 OCI_CHECK_PTR(OCI_IPC_STRING, buffer, 0); 01110 01111 OCI_RESULT(TRUE); 01112 01113 buffer[0] = 0; 01114 01115 /* ISO C functions are supposed to be "standard", but we still see specific 01116 implementations that make some usage not portable and worse not compatible. 01117 MS Windows is implementing string conversion characters (%s/%ls) of the 01118 printf/wprintf family differently from unixes ! 01119 */ 01120 01121 /* This function returns the same strings as Sql*Plus DESC command */ 01122 01123 switch(col->ocode) 01124 { 01125 case SQLT_AFC: 01126 { 01127 01128 #if defined(OCI_METADATA_WIDE) && !defined(_WINDOWS) 01129 01130 len = mtsprintf(buffer, len, MT("%lsCHAR(%i%ls)"), 01131 01132 #else 01133 01134 len = mtsprintf(buffer, len, MT("%sCHAR(%i%s)"), 01135 01136 #endif 01137 col->csfrm == SQLCS_NCHAR ? MT("N") : MT(""), 01138 (int) (col->charused == TRUE ? col->charsize : col->size), 01139 col->charused == TRUE && 01140 col->csfrm != SQLCS_NCHAR ? MT(" CHAR") : MT("")); 01141 break; 01142 } 01143 case SQLT_AVC: 01144 case SQLT_STR: 01145 case SQLT_CHR: 01146 { 01147 #if defined(OCI_METADATA_WIDE) && !defined(_WINDOWS) 01148 len = mtsprintf(buffer, len, MT("%lsVARCHAR(%i%ls)"), 01149 #else 01150 len = mtsprintf(buffer, len, MT("%sVARCHAR(%i%s)"), 01151 #endif 01152 col->csfrm == SQLCS_NCHAR ? MT("N") : MT(""), 01153 (int) (col->charused == TRUE ? col->charsize : col->size), 01154 col->charused == TRUE && 01155 col->csfrm != SQLCS_NCHAR ? MT(" CHAR") : MT("")); 01156 break; 01157 } 01158 case SQLT_NUM: 01159 { 01160 if (col->scale == -127 && col->prec > 0) 01161 { 01162 len = mtsprintf(buffer, len, MT("FLOAT(%i)"), col->prec); 01163 } 01164 else if (col->scale > 0 && col->prec > 0) 01165 { 01166 len = mtsprintf(buffer, len, MT("NUMBER(%i,%i)"), (int) col->prec, (int) col->scale); 01167 } 01168 else if (col->prec > 0) 01169 { 01170 len = mtsprintf(buffer, len, MT("NUMBER(%i)"), (int) col->prec); 01171 } 01172 else 01173 { 01174 len = mtsprintf(buffer, len, MT("NUMBER")); 01175 } 01176 01177 break; 01178 } 01179 case SQLT_INT: 01180 { 01181 len = mtsprintf(buffer, len, MT("NUMBER")); 01182 break; 01183 } 01184 case SQLT_FLT: 01185 { 01186 len = mtsprintf(buffer, len, MT("FLOAT(%i)"), (int) col->prec); 01187 break; 01188 } 01189 01190 #if OCI_VERSION_COMPILE >= OCI_10_1 01191 01192 case SQLT_BFLOAT: 01193 case SQLT_IBFLOAT: 01194 { 01195 len = mtsprintf(buffer, len, MT("BINARY FLOAT")); 01196 break; 01197 } 01198 case SQLT_BDOUBLE: 01199 case SQLT_IBDOUBLE: 01200 { 01201 len = mtsprintf(buffer, len, MT("BINARY DOUBLE")); 01202 break; 01203 } 01204 01205 #endif 01206 01207 case SQLT_LNG: 01208 { 01209 len = mtsprintf(buffer, len, MT("LONG")); 01210 break; 01211 } 01212 case SQLT_DAT: 01213 case SQLT_ODT: 01214 case SQLT_DATE: 01215 { 01216 len = mtsprintf(buffer, len, MT("DATE")); 01217 break; 01218 } 01219 case SQLT_RDD: 01220 case SQLT_RID: 01221 { 01222 len = mtsprintf(buffer, len, MT("ROWID")); 01223 break; 01224 } 01225 case SQLT_BIN: 01226 { 01227 len = mtsprintf(buffer, len, MT("RAW(%i)"), (int) col->size); 01228 break; 01229 } 01230 case SQLT_LBI: 01231 { 01232 len = mtsprintf(buffer, len, MT("LONG RAW(%i)"), (int) col->size); 01233 break; 01234 } 01235 case SQLT_RSET: 01236 { 01237 len = mtsprintf(buffer, len, MT("RESULTSET")); 01238 break; 01239 } 01240 case SQLT_CUR: 01241 { 01242 len = mtsprintf(buffer, len, MT("CURSOR")); 01243 break; 01244 } 01245 case SQLT_CLOB: 01246 { 01247 if (col->subtype == OCI_NCLOB) 01248 { 01249 len = mtsprintf(buffer, len, MT("NCLOB")); 01250 } 01251 else 01252 { 01253 len = mtsprintf(buffer, len, MT("CLOB")); 01254 } 01255 01256 break; 01257 } 01258 case SQLT_BLOB: 01259 { 01260 len = mtsprintf(buffer, len, MT("BLOB")); 01261 break; 01262 } 01263 case SQLT_BFILE: 01264 { 01265 len = mtsprintf(buffer, len, MT("BINARY FILE LOB")); 01266 break; 01267 } 01268 case SQLT_CFILE: 01269 { 01270 len = mtsprintf(buffer, len, MT("CFILE")); 01271 break; 01272 } 01273 01274 #if OCI_VERSION_COMPILE >= OCI_9_0 01275 01276 case SQLT_TIMESTAMP: 01277 { 01278 len = mtsprintf(buffer, len, MT("TIMESTAMP(%i)"), (int) col->prec); 01279 break; 01280 } 01281 case SQLT_TIMESTAMP_TZ: 01282 { 01283 len = mtsprintf(buffer, len, MT("TIMESTAMP(%i) WITH TIME ZONE"), (int) col->prec); 01284 break; 01285 } 01286 case SQLT_TIMESTAMP_LTZ: 01287 { 01288 len = mtsprintf(buffer, len, MT("TIMESTAMP(%i) WITH LOCAL TIME ZONE"), (int) col->prec); 01289 break; 01290 } 01291 case SQLT_INTERVAL_YM: 01292 { 01293 len = mtsprintf(buffer, len, MT("INTERVAL(%i) YEAR TO MONTH(%i)"), 01294 (int) col->prec, (int) col->prec2); 01295 break; 01296 } 01297 case SQLT_INTERVAL_DS: 01298 { 01299 len = mtsprintf(buffer, len, MT("INTERVAL(%i) DAY TO SECOND(%i)"), 01300 (int) col->prec, (int) col->prec2); 01301 break; 01302 } 01303 01304 #endif 01305 01306 case SQLT_REF: 01307 { 01308 len = mtsprintf(buffer, len, MT("REF")); 01309 break; 01310 } 01311 01312 #if OCI_VERSION_COMPILE >= OCI_9_0 01313 01314 case SQLT_PNTY: 01315 01316 #endif 01317 01318 case SQLT_NTY: 01319 { 01320 if (col->typinf != NULL) 01321 { 01322 len = mtsprintf(buffer, len, col->typinf->name); 01323 } 01324 else 01325 { 01326 len = mtsprintf(buffer, len, MT("NAMED TYPE")); 01327 } 01328 01329 break; 01330 } 01331 default: 01332 { 01333 mtsncat(buffer, MT("?"), (size_t) len); 01334 01335 break; 01336 } 01337 } 01338 01339 return len; 01340 } 01341 01342 /* --------------------------------------------------------------------------------------------- * 01343 * OCI_ColumnGetTypeInfo 01344 * --------------------------------------------------------------------------------------------- */ 01345 01346 OCI_TypeInfo * OCI_API OCI_ColumnGetTypeInfo 01347 ( 01348 OCI_Column *col 01349 ) 01350 { 01351 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, NULL); 01352 01353 OCI_RESULT(TRUE); 01354 01355 return col->typinf; 01356 } 01357 01358 /* --------------------------------------------------------------------------------------------- * 01359 * OCI_ColumnGetSubType 01360 * --------------------------------------------------------------------------------------------- */ 01361 01362 unsigned int OCI_API OCI_ColumnGetSubType 01363 ( 01364 OCI_Column *col 01365 ) 01366 { 01367 unsigned int type = OCI_UNKNOWN; 01368 01369 OCI_CHECK_PTR(OCI_IPC_COLUMN, col, OCI_UNKNOWN); 01370 01371 OCI_RESULT(TRUE); 01372 01373 if (col->type == OCI_CDT_LONG || 01374 col->type == OCI_CDT_LOB || 01375 col->type == OCI_CDT_FILE || 01376 col->type == OCI_CDT_TIMESTAMP || 01377 col->type == OCI_CDT_INTERVAL) 01378 { 01379 type = col->subtype; 01380 } 01381 01382 return type; 01383 } 01384 01385 /* --------------------------------------------------------------------------------------------- * 01386 * OCI_ColumnGetAttrInfo 01387 * --------------------------------------------------------------------------------------------- */ 01388 01389 boolean OCI_ColumnGetAttrInfo 01390 ( 01391 OCI_Column *col, 01392 unsigned int count, 01393 unsigned int index, 01394 size_t *p_size, 01395 int *p_type 01396 ) 01397 { 01398 if (index >= count) 01399 { 01400 *p_size = 0; 01401 *p_type = 0; 01402 01403 return FALSE; 01404 } 01405 01406 switch (col->type) 01407 { 01408 case OCI_CDT_NUMERIC: 01409 { 01410 int type = col->subtype; 01411 01412 if (type & OCI_NUM_SHORT) 01413 { 01414 *p_type = OCI_OFT_SHORT; 01415 *p_size = sizeof(short); 01416 } 01417 else if (type & OCI_NUM_INT) 01418 { 01419 *p_type = OCI_OFT_INT; 01420 *p_size = sizeof(int); 01421 } 01422 else if (type & OCI_NUM_BIGUINT) 01423 { 01424 *p_type = OCI_OFT_BIGINT; 01425 *p_size = sizeof(big_int); 01426 } 01427 else if (type & OCI_NUM_DOUBLE) 01428 { 01429 *p_type = OCI_OFT_DOUBLE; 01430 *p_size = sizeof(double); 01431 } 01432 else if (type & OCI_NUM_FLOAT) 01433 { 01434 *p_type = OCI_OFT_FLOAT; 01435 *p_size = sizeof(float); 01436 } 01437 else 01438 { 01439 /* default mapping to big_int */ 01440 01441 *p_type = OCI_OFT_BIGINT; 01442 *p_size = sizeof(big_int); 01443 } 01444 break; 01445 } 01446 case OCI_CDT_OBJECT: 01447 { 01448 *p_size = OCI_ObjectGetUserStructSize(col->typinf); 01449 *p_type = OCI_OFT_STRUCT; 01450 break; 01451 } 01452 default: 01453 { 01454 *p_size = sizeof(void *); 01455 *p_type = OCI_OFT_POINTER; 01456 break; 01457 } 01458 } 01459 01460 return TRUE; 01461 }