DCL 3.7.4
Loading...
Searching...
No Matches
OciParam Class Reference

#include <OciParam.h>

Inheritance diagram for OciParam:
SQL::Param OciData SQL::Field Object

Public Member Functions

ub2 dataType () const
 OciParam ()
virtual ~OciParam ()
bool init (SQL::Query *_query, ub4 _position)
bool doBind ()
bool onAfterExecute ()
Public Member Functions inherited from Object
virtual String toString () const
virtual void destroy ()
String className () const
bool isInstanceOf (const std::type_info &typeinfo) const
virtual const std::type_info & typeInfo () const
Public Member Functions inherited from OciData
bool onAfterFetch ()

Protected Member Functions

virtual const wchar_t * serverDataTypeName () const
virtual bool __getDataSize (size_t *_size, bool _maxsize)
virtual bool __getData (void *_buf, size_t *_size, SQL::DataType _bufType)
virtual bool __setOutputType (SQL::DataType _sqlType)
virtual void setNull ()
virtual bool __setData (_CONST void *_val, size_t _size, SQL::DataType _valType, SQL::DataType _sqlType)
bool setTimeStamp (const SQL::TimeStamp *_val, size_t _size, SQL::DataType _sqlType)
bool setInterval (const SQL::Interval *_val, size_t _size, SQL::DataType _sqlType)
sb4 inbindCallback (OCIBind *_bindp, ub4 _iter, ub4 _index, dvoid **_bufpp, ub4 *_alenp, ub1 *_piecep, dvoid **_indpp)
sb4 outbindCallback (OCIBind *_bindp, ub4 _iter, ub4 _index, dvoid **_bufpp, ub4 **_alenpp, ub1 *_piecep, dvoid **_indpp, ub2 **_rcodepp)
Protected Member Functions inherited from SQL::Param
 Param (Query *_queryHandle)
virtual ~Param ()
Protected Member Functions inherited from SQL::Field
 Field (Query *_queryHandle)
virtual ~Field ()
Protected Member Functions inherited from Object
virtual ~Object ()
 Object ()
Protected Member Functions inherited from OciData
OciConnectionconn () const
 OciData ()
 ~OciData ()
const wchar_t * serverDataTypeName () const
bool getDataSize (size_t *_size, bool _maxsize)
bool getData (void *_buf, size_t *_size, SQL::DataType _bufType)
bool getInteger (void *_buf, size_t *_size, SQL::DataType _bufType)
bool getFloat (void *_buf, size_t *_size)
bool getNumericText (char *_buf, size_t *_size)
bool getDate (SQL::Date *_buf, size_t *_size)
bool getTime (SQL::Time *_buf, size_t *_size)
bool getTimeStamp (SQL::TimeStamp *_buf)
bool getInterval (SQL::Interval *_buf)
bool getBytes (byte_t *_buf, size_t *_size)
bool writeTo (OutputStream *_buf, size_t *_size)
bool getBytesFromLob (byte_t *_buf, size_t *_size)
bool writeToFromLob (OutputStream *_output, size_t *_size)

Static Protected Member Functions

static sb4 inbindCallback (dvoid *_ictxp, OCIBind *_bindp, ub4 _iter, ub4 _index, dvoid **_bufpp, ub4 *_alenp, ub1 *_piecep, dvoid **_indpp)
static sb4 outbindCallback (dvoid *_octxp, OCIBind *_bindp, ub4 _iter, ub4 _index, dvoid **_bufpp, ub4 **_alenpp, ub1 *_piecep, dvoid **_indpp, ub2 **_rcodepp)

Additional Inherited Members

Static Public Member Functions inherited from OciData
static const wchar_t * __TYPE_NAME (ub2 _sqlt)
static ub4 __TYPE_SIZE (ub2 _sqlt, ub4 _size)
static size_t __TYPE_ALIGN (size_t _offset, ub2 _sqlt)
Protected Attributes inherited from SQL::Field
Query__queryHandle
String __name
DataType __dataType
short __precision
short __scale
Protected Attributes inherited from OciData
ub4 __position
ub4 __dynamicMode
ub4 __descType
void * __valuePtr
sb4 __valueSize
ub2 __valueType
sb2 __indicator
ub2 __actualLength
ub2 __returnCode
ub4 __callbackActualLength
BytesOutputStream__bytesOutput
size_t __dataSize
size_t __maxDataSize

Detailed Description

Definition at line 10 of file OciParam.h.

Constructor & Destructor Documentation

◆ OciParam()

OciParam::OciParam ( )

◆ ~OciParam()

OciParam::~OciParam ( )
virtual

Definition at line 63 of file OciParam.cpp.

64{
66 __DCL_ASSERT(__data.desc != NULL);
68 conn()->DescriptorFree(
69 __data.desc,
71 ) == OCI_SUCCESS
72 );
74 }
75
76 if (__buffer) {
77 free(__buffer);
78 __buffer = NULL;
79 }
80}
#define NULL
Definition Config.h:312
#define __DCL_VERIFY(expr)
Definition Object.h:396
#define __DCL_ASSERT(expr)
Definition Object.h:394
OciConnection * conn() const
Definition OciData.h:67
ub4 __descType
Definition OciData.h:19

Member Function Documentation

◆ __getData()

bool OciParam::__getData ( void * _buf,
size_t * _size,
SQL::DataType _bufType )
protectedvirtual

Reimplemented from SQL::Param.

Definition at line 187 of file OciParam.cpp.

192{
193 return OciData::getData(_buf, _size, _bufType);
194}
bool getData(void *_buf, size_t *_size, SQL::DataType _bufType)
Definition OciData.cpp:193

◆ __getDataSize()

bool OciParam::__getDataSize ( size_t * _size,
bool _maxsize )
protectedvirtual

Reimplemented from SQL::Param.

Definition at line 182 of file OciParam.cpp.

183{
184 return OciData::getDataSize(_size, _maxsize);
185}
bool getDataSize(size_t *_size, bool _maxsize)
Definition OciData.cpp:169

◆ __setData()

bool OciParam::__setData ( _CONST void * _val,
size_t _size,
SQL::DataType _valType,
SQL::DataType _sqlType )
protectedvirtual

Implements SQL::Param.

Definition at line 361 of file OciParam.cpp.

367{
368 switch (_sqlType) {
369 case SQL::typeInteger:
371 case SQL::typeFloat :
372 _sqlType = SQL::typeNumeric;
373 break;
375 _sqlType = SQL::typeIntervalDs;
376 break;
377 default:
378 ;
379 }
380
382 // 이전호출 __setData, __setOutputType의 _sqlType과의
383 // 호환성을 검사한다.
384 if (Param::__dataType != _sqlType) {
386 return false;
387 }
388 return true;
389 }
390
391 switch (_valType) {
392 case SQL::typeInteger :
393 case SQL::typeUInteger: {
394 if (_size <= sizeof(int64_t /* 2025-02-03 월 int32_t */)) {
395 uword sign = OCI_NUMBER_SIGNED;
396 if (_valType == SQL::typeUInteger)
397 sign = OCI_NUMBER_UNSIGNED;
398
399 sword status = OCINumberFromInt(
400 conn()->errorHandle(), // OCIError *err,
401 (CONST dvoid*)_val, // CONST dvoid *inum,
402 _size, // uword inum_length,
403 sign, // uword inum_s_flag,
404 &__data.number // OCINumber *number
405 );
406 if (status != OCI_SUCCESS) {
407 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
408 return false;
409 }
410 }
411 #if 0
412 // 2025-02-03 월
413 // 32bit OS에서 이것을 사용했었다.
414 else if (_size == sizeof(int64_t)) {
415 ByteString str;
416 if (_valType == SQL::typeInteger)
417 str = Int64::toByteString(*(int64_t*)_val, 10);
418 else
419 str = UInt64::toByteString(*(uint64_t*)_val, 10);
420
421 status = OCINumberFromText(
422 conn()->errorHandle(), // OCIError *err,
423 (CONST OraText*)str.data(), // CONST OraText *str,
424 str.length(), // ub4 str_length,
425 NULL, // CONST OraText *fmt,
426 0, // ub4 fmt_length,
427 NULL, // CONST OraText *nls_params,
428 0, // ub4 nls_p_length,
429 &__data.num // OCINumber *number
430 );
431 if (status != OCI_SUCCESS) {
432 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
433 return false;
434 }
435 }
436 #endif
437 else {
439 return false;
440 }
441 OciData::__valuePtr = &__data;
442 OciData::__valueSize = sizeof(OCINumber);
443 OciData::__valueType = SQLT_VNU;
445 break;
446 }
447 case SQL::typeFloat: {
448 if (_size <= sizeof(double)) {
449 sword status = OCINumberFromReal(
450 conn()->errorHandle(), // OCIError *err,
451 (CONST dvoid*)_val, // CONST dvoid *rnum,
452 _size, // uword rnum_length,
453 &__data.number // OCINumber *number
454 );
455 if (status != OCI_SUCCESS) {
456 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
457 return false;
458 }
459 }
460 else {
462 return false;
463 }
464 OciData::__valuePtr = &__data;
465 OciData::__valueSize = sizeof(OCINumber);
466 OciData::__valueType = SQLT_VNU;
468 break;
469 }
470 case SQL::typeDate: {
471 if (_size == sizeof(SQL::Date)) {
472 memset(&__data.date, 0, sizeof(OCIDate));
473 const SQL::Date* p = (const SQL::Date*)_val;
474 OCIDateSetDate(
475 &(__data.date), // OCIDate *date,
476 p->year, // sb2 year,
477 p->month, // ub1 month,
478 p->day // ub1 day
479 );
480 OciData::__valuePtr = &__data;
481 OciData::__valueSize = sizeof(OCIDate);
482 OciData::__valueType = SQLT_ODT;
483 OciData::__maxDataSize = sizeof(SQL::Date);
484 }
485 else {
487 return false;
488 }
489 break;
490 }
491 case SQL::typeTime: {
492 // Oracle에서 DATE, TIMESTAMP 모두 시간만 저장할 수 없다.
494 return false;
495 }
496 case SQL::typeTimeStamp: {
497 if (_size == sizeof(SQL::TimeStamp)) {
498 if (!setTimeStamp((const SQL::TimeStamp*)_val, _size, _sqlType))
499 return false;
500 }
501 else {
503 return false;
504 }
505 break;
506 }
507 case SQL::typeInterval: {
508 if (_size == sizeof(SQL::Interval)) {
509 if (!setInterval((const SQL::Interval*)_val, _size, _sqlType))
510 return false;
511 }
512 else {
514 return false;
515 }
516 break;
517 }
518 case SQL::typeText: {
519 if (_sqlType == SQL::typeNumeric) {
520 sword status = OCINumberFromText(
521 conn()->errorHandle(), // OCIError *err,
522 (CONST OraText*)_val, // CONST OraText *str,
523 _size, // ub4 str_length,
524 NULL, // CONST OraText *fmt,
525 0, // ub4 fmt_length,
526 NULL, // CONST OraText *nls_params,
527 0, // ub4 nls_p_length,
528 &__data.number // OCINumber *number
529 );
530 if (status != OCI_SUCCESS) {
531 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
532 return false;
533 }
534 OciData::__valuePtr = &__data;
535 OciData::__valueSize = sizeof(OCINumber);
536 OciData::__valueType = SQLT_VNU;
538 break;
539 }
540 }
541 case SQL::typeBinary: {
542 switch (_sqlType) {
543 case SQL::typeText: {
544 OciData::__valueType = SQLT_CHR;
546 break;
547 }
548 case SQL::typeBinary: {
549 OciData::__valueType = SQLT_BIN;
551 break;
552 }
553 case SQL::typeLongText: {
554 OciData::__valueType = SQLT_LNG;
556 break;
557 }
558 case SQL::typeLongBinary: {
559 OciData::__valueType = SQLT_LBI;
561 break;
562 }
563 case SQL::typeClob:
564 case SQL::typeBlob: {
565 if (OciData::__descType == 0) {
566 sword status = conn()->DescriptorAlloc(
567 &(__data.desc),
568 OCI_DTYPE_LOB
569 );
570 if (status != OCI_SUCCESS) {
572 return false;
573 }
574 OciData::__descType = OCI_DTYPE_LOB;
575 OciData::__valueSize = sizeof(OCILobLocator*);
576 OciData::__valueType = _sqlType == SQL::typeClob ? SQLT_CLOB : SQLT_BLOB;
578 }
579 break;
580 }
581 default: {
583 return false;
584 }
585 }
588 __inputValue = _val;
589 }
590 else {
591 OciData::__valuePtr = _val;
592 }
593 OciData::__valueSize = _size;
594
595 break;
596 }
598 switch (_sqlType) {
599 case SQL::typeText: {
600 OciData::__valueType = SQLT_CHR;
602 break;
603 }
604 case SQL::typeBinary: {
605 OciData::__valueType = SQLT_BIN;
607 break;
608 }
609 case SQL::typeLongText: {
610 OciData::__valueType = SQLT_LNG;
612 break;
613 }
614 case SQL::typeLongBinary: {
615 OciData::__valueType = SQLT_LBI;
617 break;
618 }
619 case SQL::typeClob:
620 case SQL::typeBlob: {
621 if (OciData::__descType == 0) {
622 sword status = conn()->DescriptorAlloc(
623 &(__data.desc),
624 OCI_DTYPE_LOB
625 );
626 if (status != OCI_SUCCESS) {
628 return false;
629 }
630 OciData::__descType = OCI_DTYPE_LOB;
631 OciData::__valueSize = sizeof(OCILobLocator*);
632 OciData::__valueType = _sqlType == SQL::typeClob ? SQLT_CLOB : SQLT_BLOB;
634 }
635 break;
636 }
637 default: {
639 return false;
640 }
641 }
643 OciData::__valueSize = _size == (size_t)-1 ? OciData::__maxDataSize : _size;
644 __inputStream = (InputStream*)_val;
645 break;
646 }
647 default: {
649 return false;
650 }
651 }
652
653 Param::__dataType = _sqlType;
654 __inputIndicator = 0;
655 return true;
656}
#define INT32_MAX
Definition Config.h:290
#define UINT32_MAX
Definition Config.h:295
#define __SET_ERROR_HANDLE(_SQLCODE)
static ByteString toByteString(int64_t _n, unsigned _base=10)
Definition Numeric.cpp:587
sword DescriptorAlloc(void **_descpp, ub4 _type, size_t _xtramem_sz=0, void **_usrmempp=NULL)
ub2 __valueType
Definition OciData.h:22
sb4 __valueSize
Definition OciData.h:21
void * __valuePtr
Definition OciData.h:20
size_t __maxDataSize
Definition OciData.h:31
bool setInterval(const SQL::Interval *_val, size_t _size, SQL::DataType _sqlType)
Definition OciParam.cpp:731
bool setTimeStamp(const SQL::TimeStamp *_val, size_t _size, SQL::DataType _sqlType)
Definition OciParam.cpp:663
@ typeBinary
Definition SQLCore.h:74
@ typeClob
Definition SQLCore.h:77
@ typeNumeric
Definition SQLCore.h:64
@ typeTime
Definition SQLCore.h:66
@ typeLongBinary
Definition SQLCore.h:76
@ typeUInteger
Definition SQLCore.h:62
@ typeTimeStamp
Definition SQLCore.h:68
@ typeBlob
Definition SQLCore.h:78
@ typeInputStream
Definition SQLCore.h:81
@ typeInterval
Definition SQLCore.h:70
@ typeIntervalDs
Definition SQLCore.h:72
@ typeDate
Definition SQLCore.h:65
@ typeText
Definition SQLCore.h:73
@ typeFloat
Definition SQLCore.h:63
@ typeInteger
Definition SQLCore.h:61
@ typeLongText
Definition SQLCore.h:75
@ eNotSupportDataType
Definition SQLCore.h:48
@ eServerError
Definition SQLCore.h:21
@ eInvalidDataSize
Definition SQLCore.h:55
@ eInvalidDataType
Definition SQLCore.h:49
static ByteString toByteString(uint64_t _u, unsigned _base=10)
Definition Numeric.cpp:692
int16_t year
Definition SQLCore.h:96
uint8_t month
Definition SQLCore.h:97
uint8_t day
Definition SQLCore.h:98

◆ __setOutputType()

bool OciParam::__setOutputType ( SQL::DataType _sqlType)
protectedvirtual

Reimplemented from SQL::Param.

Definition at line 197 of file OciParam.cpp.

200{
201 switch (_sqlType) {
202 case SQL::typeInteger:
204 case SQL::typeFloat:
205 _sqlType = SQL::typeNumeric;
206 break;
208 _sqlType = SQL::typeIntervalDs;
209 break;
210 default:
211 ;
212 }
213
215 // 이전호출 __setData, __setOutputType의 _sqlType과의
216 // 호환성을 검사한다.
217 if (Param::__dataType != _sqlType) {
219 return false;
220 }
221 return true;
222 }
223
224 switch (_sqlType) {
225 case SQL::typeInteger:
227 case SQL::typeFloat:
228 _sqlType = SQL::typeNumeric;
229 case SQL::typeNumeric: {
230 OciData::__valueSize = sizeof(OCINumber);
231 OciData::__valueType = SQLT_VNU;
233 break;
234 }
235 case SQL::typeDate: {
236 OciData::__valueSize = sizeof(OCIDate);
237 OciData::__valueType = SQLT_ODT;
238 OciData::__maxDataSize = sizeof(SQL::Date);
239 break;
240 }
241 case SQL::typeTime: {
242 // Oracle에서 DATE, TIMESTAMP은 모두 TIME만 저장할 수 없다.
244 break;
245 }
248 if (OciData::__descType == 0) {
249 ub2 dataType = SQLT_TIMESTAMP;
250 ub4 descType = OCI_DTYPE_TIMESTAMP;
251 if (_sqlType == SQL::typeTimeStampTz) {
252 dataType = SQLT_TIMESTAMP_TZ;
253 descType = OCI_DTYPE_TIMESTAMP_TZ;
254 }
255
256 sword status = conn()->DescriptorAlloc(
257 &(__data.desc),
258 descType
259 );
260 if (status != OCI_SUCCESS) {
262 return false;
263 }
264 OciData::__descType = descType;
265 OciData::__valueSize = sizeof(OCIDateTime*);
267 OciData::__maxDataSize = sizeof(SQL::TimeStamp);
268 }
269 break;
270 }
272 _sqlType = SQL::typeIntervalDs;
274 case SQL::typeIntervalDs: {
275 if (OciData::__descType == 0) {
276 ub2 dataType = SQLT_INTERVAL_DS;
277 ub4 descType = OCI_DTYPE_INTERVAL_DS;
278 if (_sqlType == SQL::typeIntervalYm) {
279 dataType = SQLT_INTERVAL_YM;
280 descType = OCI_DTYPE_INTERVAL_YM;
281 }
282
283 sword status = conn()->DescriptorAlloc(
284 &(__data.desc),
285 OCI_DTYPE_INTERVAL_DS
286 );
287 if (status != OCI_SUCCESS) {
289 return false;
290 }
291 OciData::__descType = descType;
292 OciData::__valueSize = sizeof(OCIInterval*);
294 OciData::__maxDataSize = sizeof(SQL::Interval);
295 }
296 break;
297 }
298 case SQL::typeText: {
300 OciData::__valueType = SQLT_CHR;
301 OciData::__maxDataSize = 4000; // AFC ==> 2000
302 break;
303 }
304 case SQL::typeBinary: {
306 OciData::__valueType = SQLT_BIN;
308 break;
309 }
310 case SQL::typeLongText: {
312 OciData::__valueType = SQLT_LNG;
314 break;
315 }
316 case SQL::typeLongBinary: {
318 OciData::__valueType = SQLT_LBI;
320 break;
321 }
322 case SQL::typeClob:
323 case SQL::typeBlob: {
324 if (OciData::__descType == 0) {
325 sword status = conn()->DescriptorAlloc(
326 &(__data.desc),
327 OCI_DTYPE_LOB
328 );
329 if (status != OCI_SUCCESS) {
331 return false;
332 }
333 OciData::__descType = OCI_DTYPE_LOB;
334 OciData::__valueSize = sizeof(OCILobLocator*);
335 OciData::__valueType = _sqlType == SQL::typeClob ? SQLT_CLOB : SQLT_BLOB;
337 }
338 break;
339 }
340 default: {
342 return false;
343 }
344 }
345
346 Param::__dataType = _sqlType;
347 return true;
348}
ub2 dataType() const
Definition OciParam.h:34
@ typeTimeStampTz
Definition SQLCore.h:69
@ typeIntervalYm
Definition SQLCore.h:71

◆ dataType()

ub2 OciParam::dataType ( ) const
inline

Definition at line 34 of file OciParam.h.

34{ return OciData::__valueType; }

◆ doBind()

bool OciParam::doBind ( )

Definition at line 822 of file OciParam.cpp.

823{
824 if (OciData::__valueType == 0) {
825 // then out bind only param
828 __DCL_ASSERT(__buffer == NULL);
829 }
830
831 // __DCL_TRACE3_N("%ls, %d, %p\n", Param::__name.data(),
832 // OciData::__valueSize, OciData::__valuePtr);
833 OCIBind* bindp = NULL;
834 sword status = OCIBindByPos(
835 query()->stmtHandle(), // OCIStmt *stmtp,
836 &bindp, // OCIBind **bindpp,
837 conn()->errorHandle(), // OCIError *errhp,
838 OciData::__position, // ub4 position,
839 NULL, // dvoid *valuep,
840 OciData::__valueSize, // sb4 value_sz,
841 OciData::__valueType, // ub2 dty,
842 &__inputIndicator, // dvoid *indp,
843 NULL, // ub2 *alenp,
844 &(OciData::__returnCode), // ub2 *rcodep,
845 0, // ub4 maxarr_len,
846 NULL, // ub4 *curelep,
847 OciData::__dynamicMode // ub4 mode
848 );
849 if (status != OCI_SUCCESS) {
850 __DCL_TRACE2_N(L"OCIBindByPos status[%d] position[%d]\n",
851 status, OciData::__position);
852 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
853 return false;
854 }
855 __DCL_ASSERT(bindp != NULL); // bindDynamic은 bindByPos 이후에
856 if (OciData::__dynamicMode == OCI_DATA_AT_EXEC) {
857 status = OCIBindDynamic(
858 bindp, // OCIBind *bindp,
859 conn()->errorHandle(), // OCIError *errhp,
860 this, // dvoid *ictxp,
861 OciParam::inbindCallback, // OCICallbackInBind (icbfp)
862 this, // dvoid *octxp
863 OciParam::outbindCallback // OCICallbackOutBind (ocbfp)
864 );
865 if (status != OCI_SUCCESS) {
866 __DCL_TRACE2_N(L"OCIBindDynamic status[%d] position[%d]\n",
867 status, OciData::__position);
868 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
869 return false;
870 }
871 }
872
873 return true;
874}
#define __DCL_TRACE2_N(fmt, arg1, arg2)
virtual OciQuery * query() const =0
ub4 __dynamicMode
Definition OciData.h:17
ub4 __position
Definition OciData.h:16
ub2 __returnCode
Definition OciData.h:26
static sb4 inbindCallback(dvoid *_ictxp, OCIBind *_bindp, ub4 _iter, ub4 _index, dvoid **_bufpp, ub4 *_alenp, ub1 *_piecep, dvoid **_indpp)
Definition OciParam.cpp:876
static sb4 outbindCallback(dvoid *_octxp, OCIBind *_bindp, ub4 _iter, ub4 _index, dvoid **_bufpp, ub4 **_alenpp, ub1 *_piecep, dvoid **_indpp, ub2 **_rcodepp)
Definition OciParam.cpp:898

◆ inbindCallback() [1/2]

sb4 OciParam::inbindCallback ( dvoid * _ictxp,
OCIBind * _bindp,
ub4 _iter,
ub4 _index,
dvoid ** _bufpp,
ub4 * _alenp,
ub1 * _piecep,
dvoid ** _indpp )
staticprotected

Definition at line 876 of file OciParam.cpp.

886{
887 return ((OciParam*)_ictxp)->inbindCallback(
888 _bindp,
889 _iter,
890 _index,
891 _bufpp,
892 _alenp,
893 _piecep,
894 _indpp
895 );
896}

◆ inbindCallback() [2/2]

sb4 OciParam::inbindCallback ( OCIBind * _bindp,
ub4 _iter,
ub4 _index,
dvoid ** _bufpp,
ub4 * _alenp,
ub1 * _piecep,
dvoid ** _indpp )
protected

Definition at line 922 of file OciParam.cpp.

931{
932 __DCL_ASSERT(OciData::__dynamicMode == OCI_DATA_AT_EXEC);
933
934#if defined(__DCL_DEBUG) && 0
935 switch (*_piecep) {
936 case OCI_ONE_PIECE:
937 __DCL_TRACE1_N("OCI_ONE_PIECE [%d]\n", __position);
938 break;
939 case OCI_FIRST_PIECE:
940 __DCL_TRACE1_N("OCI_FIRST_PIECE [%d]\n", __position);
941 break;
942 case OCI_NEXT_PIECE:
943 __DCL_TRACE1_N("OCI_NEXT_PIECE [%d]\n", __position);
944 break;
945 case OCI_LAST_PIECE:
946 __DCL_TRACE1_N("OCI_LAST_PIECE [%d]\n", __position);
947 }
948#endif
949
950 if (__inputIndicator == -1) {
951 *_bufpp = NULL;
952 *_alenp = 0;
953 *_piecep = OCI_ONE_PIECE;
954 *_indpp = &__inputIndicator;
955 return OCI_CONTINUE;
956 }
957
959 if (OciData::__descType != OCI_DTYPE_LOB) {
960 // OCI_DTYPE_TIMESTAMP, OCI_DTYPE_TIMESTAMP_TZ
961 // OCI_DTYPE_INTERVAL_YM, OCI_DTYPE_INTERVAL_DS
962 *_bufpp = __data.desc;
963 *_alenp = sizeof(void*);
964 }
965 else {
966 // outbindCallback 이후 onAfterExecute 에서 OCILobWrite 한다.
967 __inputIndicator = -1;
968 *_bufpp = NULL;
969 *_alenp = 0;
970 }
971 *_piecep = OCI_ONE_PIECE;
972 *_indpp = &__inputIndicator;
973 return OCI_CONTINUE;
974 }
975 else {
976 if (__inputStream) {
978 || OciData::__valueType == SQLT_BIN
979 || OciData::__valueType == SQLT_LNG
980 || OciData::__valueType == SQLT_LBI);
981
982 if (!__buffer) {
983 __buffer = malloc(__DYNAMIC_BUFFER_SIZE);
984 if (!__buffer) {
986 return OCI_ERROR;
987 }
988 }
989
990 __DCL_ASSERT(__buffer != NULL);
991 size_t read = __MIN((size_t)OciData::__valueSize, __DYNAMIC_BUFFER_SIZE);
992
993 if (read) {
994 try {
995 read = __inputStream->read(__buffer, read);
996 }
997 catch (IOException* _cause) {
998 __SET_ERROR_MSG(UTF8Encoder::encode(_cause->toStringAll()));
999 _cause->destroy();
1000 return OCI_ERROR;
1001 }
1002 }
1003
1004 if (*_piecep == OCI_FIRST_PIECE) {
1005 if (read == (size_t)OciData::__valueSize)
1006 *_piecep = OCI_ONE_PIECE;
1007 }
1008 else {
1009 // OCI_NEXT_PIECE
1010 if (read == 0 || read == (size_t)OciData::__valueSize)
1011 *_piecep = OCI_LAST_PIECE;
1012 }
1013
1014 OciData::__valueSize -= read;
1015 *_bufpp = __buffer;
1016 *_alenp = read;
1017 *_indpp = NULL;
1018 }
1019 else {
1020 // 나머지 경우 OciData::__valuePtr는
1021 // 외부에서 받은 char*, byte_t* 그리고 &OciParam::__data 이다.
1022 *_bufpp = OciData::__valuePtr;
1023 *_alenp = OciData::__valueSize;
1024 *_piecep = OCI_ONE_PIECE;
1025 *_indpp = &__inputIndicator;
1026 }
1027 }
1028 return OCI_CONTINUE;
1029}
#define __DCL_TRACE1_N(fmt, arg)
#define __SET_ERROR_MSG(_message)
#define __DYNAMIC_BUFFER_SIZE
Definition OciData.h:11
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
@ eOutOfMemory
Definition SQLCore.h:24
size_t __MIN(size_t x, size_t y)
Definition size_t.h:27

◆ init()

bool OciParam::init ( SQL::Query * _query,
ub4 _position )

Definition at line 87 of file OciParam.cpp.

88{
89 Param::__queryHandle = _queryHandle;
90 OciData::__position = _position;
91 OciData::__dynamicMode = OCI_DATA_AT_EXEC;
92
93 return true;
94}

◆ onAfterExecute()

bool OciParam::onAfterExecute ( )

Definition at line 96 of file OciParam.cpp.

97{
98 if ((OciData::__descType == OCI_DTYPE_LOB)
99 && (__inputValue || __inputStream)) {
100 if (__inputValue) {
101 ub4 byte_amt = OciData::__valueSize;
102 sword status = OCILobWrite(
103 conn()->svcHandle(), // OCISvcCtx *svchp,
104 conn()->errorHandle(), // OCIError *errhp,
105 (OCILobLocator*)__data.desc, // OCILobLocator *locp,
106 &byte_amt, // ub4 *amtp,
107 1, // ub4 offset,
108 __inputValue, // void *bufp,
109 OciData::__valueSize, // ub4 buflen,
110 OCI_ONE_PIECE, // ub1 piece,
111 NULL, // void* ctxp,
112 (OCICallbackLobWrite)NULL, // OCICallbackLobWrite(cbfp)
113 0, // ub2 csid,
114 SQLCS_IMPLICIT // ub1 csfrm
115 );
116 __DCL_TRACE2_N(L"OCILobWrite [%d] byte_amt[%d]\n", status, byte_amt);
117 if (status != OCI_SUCCESS) {
118 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
119 return false;
120 }
121 }
122 else {
123 try {
124 char buf[4096];
125 size_t total = 0;
126 for ( ; ; ) {
127 size_t n = __MIN(OciData::__valueSize - total, sizeof(buf));
128 n = __inputStream->read(buf, n);
129 ub4 byte_amt = OciData::__valueSize;
130
131 ub1 piece = OCI_ONE_PIECE;
132 if (total == 0) {
133 piece = n < sizeof(buf) ? OCI_ONE_PIECE : OCI_FIRST_PIECE;
134 }
135 else {
136 piece = n < sizeof(buf) ? OCI_LAST_PIECE : OCI_NEXT_PIECE;
137 }
138
139 sword status = OCILobWrite(
140 conn()->svcHandle(), // OCISvcCtx *svchp,
141 conn()->errorHandle(), // OCIError *errhp,
142 (OCILobLocator*)__data.desc, // OCILobLocator *locp,
143 &byte_amt, // ub4 *amtp,
144 1 + total, // ub4 offset,
145 __inputValue, // void *bufp,
146 OciData::__valueSize, // ub4 buflen,
147 piece, // ub1 piece,
148 NULL, // void* ctxp,
149 (OCICallbackLobWrite)NULL, // OCICallbackLobWrite(cbfp)
150 0, // ub2 csid,
151 SQLCS_IMPLICIT // ub1 csfrm
152 );
153 __DCL_TRACE2_N(L"OCILobWrite [%d] byte_amt[%d]\n", status, byte_amt);
154 if (status != OCI_SUCCESS) {
155 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
156 return false;
157 }
158 total += byte_amt;
159 }
160 }
161 catch (IOException* _cause) {
162 __SET_ERROR_MSG(UTF8Encoder::encode(_cause->toStringAll()));
163 _cause->destroy();
164 return false;
165 }
166 }
167
168 }
169 __inputIndicator = -1;
170 __inputStream = NULL;
171 __inputValue = NULL;
172
173 // calc output datasize
174 return OciData::onAfterFetch();
175}
bool onAfterFetch()
Definition OciData.cpp:75

◆ outbindCallback() [1/2]

sb4 OciParam::outbindCallback ( dvoid * _octxp,
OCIBind * _bindp,
ub4 _iter,
ub4 _index,
dvoid ** _bufpp,
ub4 ** _alenpp,
ub1 * _piecep,
dvoid ** _indpp,
ub2 ** _rcodepp )
staticprotected

Definition at line 898 of file OciParam.cpp.

909{
910 return ((OciParam*)_octxp)->outbindCallback(
911 _bindp,
912 _iter,
913 _index,
914 _bufpp,
915 _alenpp,
916 _piecep,
917 _indpp,
918 _rcodepp
919 );
920}

◆ outbindCallback() [2/2]

sb4 OciParam::outbindCallback ( OCIBind * _bindp,
ub4 _iter,
ub4 _index,
dvoid ** _bufpp,
ub4 ** _alenpp,
ub1 * _piecep,
dvoid ** _indpp,
ub2 ** _rcodepp )
protected

Definition at line 1031 of file OciParam.cpp.

1041{
1042 __DCL_ASSERT(OciData::__dynamicMode == OCI_DATA_AT_EXEC);
1043
1044#if defined(__DCL_DEBUG) && 0
1045 if (_index == 0) {
1046 ub4 rows = 0;
1047 ub4 size = sizeof(rows);
1048 sword status = OCIAttrGet(
1049 _bindp, // const void *trgthndlp
1050 OCI_HTYPE_BIND, // ub4 trghndltyp
1051 &rows, // void *attributep
1052 &size, // ub4 *sizep
1053 OCI_ATTR_ROWS_RETURNED, // ub4 attrtype
1054 conn()->errorHandle() // OCIError *errhp
1055 );
1056 __DCL_ASSERT(size == sizeof(rows));
1057 if (status != OCI_SUCCESS) {
1058 return OCI_ERROR;
1059 }
1060 }
1061 switch (*_piecep) {
1062 case OCI_ONE_PIECE :
1063 __DCL_TRACE1_N(L"OCI_ONE_PIECE [%d]\n", __position);
1064 break;
1065 case OCI_FIRST_PIECE :
1066 __DCL_TRACE1_N(L"OCI_FIRST_PIECE [%d]\n", __position);
1067 break;
1068 case OCI_NEXT_PIECE :
1069 __DCL_TRACE1_N(L"OCI_NEXT_PIECE [%d]\n", __position);
1070 break;
1071 case OCI_LAST_PIECE :
1072 __DCL_TRACE1_N(L"OCI_LAST_PIECE [%d]\n", __position);
1073 }
1074#endif
1075
1076 if (OciData::__valueType == SQLT_CHR
1077 || OciData::__valueType == SQLT_BIN
1078 || OciData::__valueType == SQLT_LNG
1079 || OciData::__valueType == SQLT_LBI) {
1080 if (*_piecep == OCI_ONE_PIECE)
1081 *_piecep = OCI_FIRST_PIECE;
1082
1083 if (*_piecep == OCI_FIRST_PIECE) {
1084 if (!__buffer) {
1085 __buffer = malloc(__DYNAMIC_BUFFER_SIZE);
1086 if (!__buffer) {
1088 return OCI_ERROR;
1089 }
1090 }
1091
1092 OciData::__valuePtr = __buffer;
1094 __bytesOutput->reset();
1095 }
1096 else {
1097 // 두번째 PIECE 부터는 이전 데이터를 내부 스트림에 보관한다.
1099 OciData::__bytesOutput = new BytesOutputStream();
1102 return OCI_ERROR;
1103 }
1104 }
1105
1107 try {
1111 );
1112 }
1113 catch(IOException* _cause) {
1114 __SET_ERROR_MSG(UTF8Encoder::encode(_cause->toStringAll()));
1115 _cause->destroy();
1116 return OCI_ERROR;
1117 }
1118 }
1119
1122
1123 *_bufpp = OciData::__valuePtr;
1124 *_alenpp = &(OciData::__callbackActualLength);
1125 *_indpp = &(OciData::__indicator);
1126 *_rcodepp = &(OciData::__returnCode);
1127 }
1128 else {
1129 // 버퍼가 OCIDateTime*, OCILogLocator*, OCIRowid* 와 같은
1130 // void*의 디스크립터 일 경우 ppvBuffer에는 이들 디스크립터의
1131 // 값을 넣어 주어야 한다.
1132 // 그러나, OciData::getData에서는 OciData::__valuePtr를 사용하여
1133 // 값을 얻기 때문에 이들의 주소를 할당해야 한다.
1134 // OCIDateTime의 경우 *(OCIDateTime**)OciData::__valuePtr 와 같이 사용된다.
1135 //
1136 // OCINumber, OCIDate와 같은 경우 이들의 포인터를 할당한다.
1137 if (OciData::__descType) {
1138 OciData::__valuePtr = &__data.desc;
1139 OciData::__callbackActualLength = sizeof(void*);
1140 *_bufpp = __data.desc;
1141 }
1142 else {
1143 OciData::__valuePtr = &__data;
1145 *_bufpp = &__data;
1146 }
1148
1149 *_piecep = OCI_ONE_PIECE;
1150 *_alenpp = &(OciData::__callbackActualLength);//NULL;
1151 *_indpp = &(OciData::__indicator);
1152 *_rcodepp = &(OciData::__returnCode);
1153 }
1154
1155 return OCI_CONTINUE;
1156}
sb2 __indicator
Definition OciData.h:24
ub4 __callbackActualLength
Definition OciData.h:27
BytesOutputStream * __bytesOutput
Definition OciData.h:29

◆ serverDataTypeName()

const wchar_t * OciParam::serverDataTypeName ( ) const
protectedvirtual

Implements SQL::Field.

Definition at line 177 of file OciParam.cpp.

178{
180}
const wchar_t * serverDataTypeName() const
Definition OciData.cpp:164

◆ setInterval()

bool OciParam::setInterval ( const SQL::Interval * _val,
size_t _size,
SQL::DataType _sqlType )
protected

Definition at line 731 of file OciParam.cpp.

736{
737 OciConnection* _conn = conn();
738 sword status = OCI_SUCCESS;
739
740 if (OciData::__descType == 0) {
741 ub2 dataType = SQLT_INTERVAL_DS;
742 ub4 descType = OCI_DTYPE_INTERVAL_DS;
743 if (_sqlType == SQL::typeIntervalYm) {
744 dataType = SQLT_INTERVAL_YM;
745 descType = OCI_DTYPE_INTERVAL_YM;
746 }
747
748 status = _conn->DescriptorAlloc(
749 &(__data.desc),
750 descType
751 );
752 if (status != OCI_SUCCESS) {
754 return false;
755 }
756
757 OciData::__descType = descType;
759 OciData::__maxDataSize = sizeof(SQL::Interval);
760 }
761
762 if (OciData::__valueType == SQLT_INTERVAL_YM) {
763 // set zero
764 // 이부분이 빠지면 Query::execute에서
765 status = OCIIntervalFromText(
766 conn()->sessionHandle(), // dvoid *hndl,
767 conn()->errorHandle(), // OCIError *err,
768 (CONST OraText*)"0-0", // CONST OraText *inpstring,
769 3, // size_t str_len,
770 (OCIInterval*)__data.desc // OCIInterval *result
771 );
772 if (status == OCI_SUCCESS)
773 status = OCIIntervalSetYearMonth(
774 conn()->sessionHandle(), // dvoid *hndl,
775 conn()->errorHandle(), // OCIError *err,
776 _val->years, // sb4 yr,
777 _val->months, // sb4 mnth,
778 (OCIInterval*)__data.desc // OCIInterval *result
779 );
780 }
781 else {
782 status = OCIIntervalFromText(
783 conn()->sessionHandle(), // dvoid *hndl,
784 conn()->errorHandle(), // OCIError *err,
785 (CONST OraText*)"0 00:00:00", // CONST OraText *inpstring,
786 10, // size_t str_len,
787 (OCIInterval*)__data.desc // OCIInterval *result
788 );
789 if (status == OCI_SUCCESS)
790 status = OCIIntervalSetDaySecond(
791 conn()->sessionHandle(), // dvoid *hndl,
792 conn()->errorHandle(), // OCIError *err,
793 _val->days, // sb4 dy,
794 _val->hours, // sb4 hr,
795 _val->mins, // sb4 mm,
796 _val->secs, // sb4 ss,
797 _val->fracs, // sb4 fsec,
798 (OCIInterval*)__data.desc // OCIInterval *result
799 );
800 }
801#if defined(__DCL_DEBUG) && 1
802 if (status == OCI_SUCCESS) {
803 ub4 valid = 0;
804 status = OCIIntervalCheck(
805 conn()->sessionHandle(), // dvoid *hndl,
806 conn()->errorHandle(), // OCIError *err,
807 (CONST OCIInterval*)__data.desc, // CONST OCIInterval *interval,
808 &valid // ub4 *valid
809 );
810 }
811#endif
812
813 if (status != OCI_SUCCESS) {
815 return false;
816 }
817
818 OciData::__valueSize = sizeof(OCIInterval*);
819 return true;
820}
int32_t years
Definition SQLCore.h:126
int32_t days
Definition SQLCore.h:128
int8_t hours
Definition SQLCore.h:129
int8_t mins
Definition SQLCore.h:130
int32_t fracs
Definition SQLCore.h:132
int8_t months
Definition SQLCore.h:127
int8_t secs
Definition SQLCore.h:131

◆ setNull()

void OciParam::setNull ( )
protectedvirtual

Implements SQL::Param.

Definition at line 350 of file OciParam.cpp.

351{
352 // FIX 2025-02-10 See 753 OCIBindByPos
353 Param::__dataType = SQL::typeUnknown;
354 OciData::__valueType = SQLT_CHR;
358 __inputIndicator = -1;
359}
@ typeUnknown
Definition SQLCore.h:60

◆ setTimeStamp()

bool OciParam::setTimeStamp ( const SQL::TimeStamp * _val,
size_t _size,
SQL::DataType _sqlType )
protected

Definition at line 663 of file OciParam.cpp.

668{
669 OciConnection* _conn = conn();
670 sword status = OCI_SUCCESS;
671
672 if (OciData::__descType == 0) {
673 ub2 dataType = SQLT_TIMESTAMP;
674 ub4 descType = OCI_DTYPE_TIMESTAMP;
675 if (_sqlType == SQL::typeTimeStampTz) {
676 dataType = SQLT_TIMESTAMP_TZ;
677 descType = OCI_DTYPE_TIMESTAMP_TZ;
678 }
679
680 status = _conn->DescriptorAlloc(
681 &(__data.desc),
682 descType
683 );
684 if (status != OCI_SUCCESS) {
686 return false;
687 }
688
689 OciData::__descType = descType;
691 OciData::__maxDataSize = sizeof(SQL::TimeStamp);
692 }
693
694 ByteString strTz;
695 OraText* pTz = NULL;
696 size_t nTzLen = 0;
697 if (_sqlType == SQL::typeTimeStampTz) {
698 strTz = ByteString::format(
699 // 6,
700 "%02d:%02d",
701 _val->tzoff / 60,
702 __ABS(_val->tzoff % 60)
703 );
704 pTz = (OraText*)strTz.data();
705 nTzLen = strTz.length();
706 }
707
708 status = OCIDateTimeConstruct(
709 conn()->sessionHandle(), // dvoid *hndl,
710 conn()->errorHandle(), // OCIError *err,
711 (OCIDateTime*)__data.desc, // OCIDateTime *datetime,
712 _val->year, // sb2 year,
713 _val->month, // ub1 month,
714 _val->day, // ub1 day,
715 _val->hour, // ub1 hour,
716 _val->min, // ub1 min,
717 _val->sec, // ub1 sec,
718 _val->frac, // ub4 fsec,
719 pTz, // OraText *timezone,
720 nTzLen // size_t timezone_length
721 );
722 if (status != OCI_SUCCESS) {
724 return false;
725 }
726
727 OciData::__valueSize = sizeof(OCIDateTime*);
728 return true;
729}
#define __ABS(n)
Definition MyParam.cpp:145
uint32_t frac
Definition SQLCore.h:118
int16_t tzoff
Definition SQLCore.h:119
uint8_t min
Definition SQLCore.h:116
uint8_t sec
Definition SQLCore.h:117
uint8_t hour
Definition SQLCore.h:115
uint8_t day
Definition SQLCore.h:114
int16_t year
Definition SQLCore.h:112
uint8_t month
Definition SQLCore.h:113

The documentation for this class was generated from the following files: