DCL 4.1
Loading...
Searching...
No Matches
OciParam.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#include <oci.h>
4
5#include <stdlib.h> // malloc, free
6
7#include <dcl/Object.h>
8#if __DCL_HAVE_ALLOC_DEBUG
9#undef __DCL_ALLOC_LEVEL
10#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
11#endif
12
13#include <dcl/Numeric.h>
14#include <dcl/InputStream.h>
15#include <dcl/OutputStream.h>
17#include <dcl/Charset.h>
18#include <dcl/SQLCore.h>
19
20#include "OciConnection.h"
21#include "OciQuery.h"
22#include "OciParam.h"
23
24#define __TRACE_THIS 0
25#if __TRACE_THIS
26#define __DCL_TRACE0_N __DCL_TRACE0
27#define __DCL_TRACE1_N __DCL_TRACE1
28#define __DCL_TRACE2_N __DCL_TRACE2
29#define __DCL_TRACE3_N __DCL_TRACE3
30#define __DCL_TRACE4_N __DCL_TRACE4
31#else
32#define __DCL_TRACE0_N(fmt)
33#define __DCL_TRACE1_N(fmt, arg)
34#define __DCL_TRACE2_N(fmt, arg1, arg2)
35#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
36#define __DCL_TRACE4_N(fmt, arg1, arg2, arg3, arg4)
37#endif
38
39#undef __THIS_FILE__
40static const wchar_t __THIS_FILE__[] = __T("dcl/sql/OciParam.cpp");
41
42__DCL_BEGIN_NAMESPACE
43
44#undef __SET_ERROR
45#define __SET_ERROR(_error, status, pError) \
46 conn()->setErrorStatus(_error, status, pError, \
47 true, __THIS_FILE__, __LINE__)
48
50
52 : Param(NULL)
53{
54 __bind = NULL;
55 __inputIndicator = -1;
56
57 __buffer = NULL;
58 __inputStream = NULL;
59}
60
62{
64 __DCL_ASSERT(__data.desc != NULL);
66 conn()->OCIDescriptorFree(
67 __data.desc,
69 ) == OCI_SUCCESS);
71 }
72
73 if (__buffer) {
74 free(__buffer);
75 __buffer = NULL;
76 }
77}
78
79bool OciParam::init(SQL::Query* _queryHandle, ub4 _position)
80{
81 Param::__queryHandle = _queryHandle;
82
83 OciData::__queryHandle = (OciQuery*)_queryHandle;
84 OciData::__position = _position;
85 OciData::__dynamicMode = OCI_DATA_AT_EXEC;
86
87 return true;
88}
89
91{
92 __inputIndicator = -1;
93 __inputStream = NULL;
94
95 // calc output datasize
96 return OciData::onAfterFetch();
97}
98
99// out bind support
102 )
103{
104 if (Param::__dataType != SQL::typeUnknown) {
105 if (Param::__dataType != _dataType) {
107 return false;
108 }
109 return true;
110 }
111
112 OciConnection* pConnection = conn();
113 sword status = OCI_SUCCESS;
114
115 switch(_dataType) {
116 case SQL::typeInteger:
118 case SQL::typeFloat:
120 case SQL::typeNumeric: {
121 OciData::__valueSize = sizeof(OCINumber);
122 OciData::__dataType = SQLT_VNU;
124 break;
125 }
126 case SQL::typeTime: {
127 // Oracle에서 DATE, TIMESTAMP은 모두 TIME만 저장할 수 없다.
129 break;
130 }
131 case SQL::typeDate:
133 case SQL::typeTimeStamp :
135 ub2 dataType = SQLT_TIMESTAMP;
136 ub4 descType = OCI_DTYPE_TIMESTAMP;
138 dataType = SQLT_TIMESTAMP_TZ;
139 descType = OCI_DTYPE_TIMESTAMP_TZ;
140 }
141
142 status = pConnection->OCIDescriptorAlloc(
143 &(__data.desc),
144 descType
145 );
146 if (status != OCI_SUCCESS) {
148 return false;
149 }
150 OciData::__descType = descType;
151 OciData::__valueSize = sizeof(OCIDateTime*);
152 OciData::__dataType = dataType;
154 break;
155 }
159 case SQL::typeIntervalDs: {
160 ub2 dataType = SQLT_INTERVAL_DS;
161 ub4 descType = OCI_DTYPE_INTERVAL_DS;
163 dataType = SQLT_INTERVAL_YM;
164 descType = OCI_DTYPE_INTERVAL_YM;
165 }
166
167 status = pConnection->OCIDescriptorAlloc(
168 &(__data.desc),
169 OCI_DTYPE_INTERVAL_DS
170 );
171 if (status != OCI_SUCCESS) {
173 return false;
174 }
175 OciData::__descType = descType;
176 OciData::__valueSize = sizeof(OCIInterval*);
177 OciData::__dataType = dataType;
179 break;
180 }
181 case SQL::typeText: {
183 OciData::__dataType = SQLT_CHR;
184 OciData::__maxDataSize = 4000; // AFC ==> 2000
185 break;
186 }
187 case SQL::typeBinary: {
189 OciData::__dataType = SQLT_BIN;
191 break;
192 }
193 case SQL::typeLongText: {
195 OciData::__dataType = SQLT_LNG;
197 break;
198 }
199 case SQL::typeLongBinary: {
201 OciData::__dataType = SQLT_LBI;
203 break;
204 }
205 case SQL::typeClob: {
206 status = pConnection->OCIDescriptorAlloc(
207 &(__data.desc),
208 OCI_DTYPE_LOB
209 );
210 if (status != OCI_SUCCESS) {
212 return false;
213 }
214 OciData::__descType = OCI_DTYPE_LOB;
215 OciData::__valueSize = sizeof(OCILobLocator*);
216 OciData::__dataType = SQLT_CLOB;
218 break;
219 }
220 case SQL::typeBlob: {
221 status = pConnection->OCIDescriptorAlloc(
222 &(__data.desc),
223 OCI_DTYPE_LOB
224 );
225 if (status != OCI_SUCCESS) {
227 return false;
228 }
229 OciData::__descType = OCI_DTYPE_LOB;
230 OciData::__valueSize = sizeof(OCILobLocator*);
231 OciData::__dataType = SQLT_BLOB;
233 break;
234 }
235 default: {
237 return false;
238 }
239 }
240
241 Param::__dataType = _dataType;
242 return true;
243}
244
246{
247 return OciData::__indicator == -1;
248}
249
250const wchar_t* OciParam::serverDataTypeName() const
251{
253}
254
256 size_t* _size,
257 bool _maxSize
258 )
259{
260 return OciData::getDataSize(_size, _maxSize);
261}
262
264 void* _pv,
265 size_t* _size, // IN, OUT
267 )
268{
269 return OciData::getData(_pv, _size, _dataType);
270}
271
273{
274 // FIX 2025-02-10 See 753 OCIBindByPos
275 Param::__dataType = SQL::typeUnknown;
276 OciData::__dataType = SQLT_CHR;
280 __inputIndicator = -1;
281}
282
284 _CONST void* _pv,
285 size_t _size,
287 SQL::DataType _assignType
288 )
289{
290 switch(_assignType) {
291 case SQL::typeInteger:
293 case SQL::typeFloat :
294 _assignType = SQL::typeNumeric;
295 break;
296 case SQL::typeDate:
297 _assignType = SQL::typeTimeStamp;
298 break;
300 _assignType = SQL::typeIntervalDs;
301 break;
302 default :
303 ;
304 }
305
306 if (Param::__dataType != SQL::typeUnknown) {
307 if (Param::__dataType != _assignType) {
309 return false;
310 }
311 }
312
313 OCIError* pError = conn()->errorHandle();
314 sword status = OCI_SUCCESS;
315
316 switch(_dataType) {
317 case SQL::typeInteger :
318 case SQL::typeUInteger: {
319 if (_size <= sizeof(int64_t /* 2025-02-03 월 int32_t */)) {
320 uword sign = OCI_NUMBER_SIGNED;
322 sign = OCI_NUMBER_UNSIGNED;
323
324 status = ::OCINumberFromInt(
325 pError, // OCIError *err,
326 (CONST dvoid*)_pv, // CONST dvoid *inum,
327 _size, // uword inum_length,
328 sign, // uword inum_s_flag,
329 &__data.num // OCINumber *number
330 );
331 if (status != OCI_SUCCESS) {
332 __SET_ERROR(SQL::eServerError, status, pError);
333 return false;
334 }
335 }
336 #if 0 // 2025-02-03 월
337 else if (_size == sizeof(int64_t)) {
338 ByteString str;
340 str = Int64::toByteString(*(int64_t*)_pv, 10);
341 else
342 str = UInt64::toByteString(*(uint64_t*)_pv, 10);
343
344 status = ::OCINumberFromText(
345 pError, // OCIError *err,
346 (CONST OraText*)str.data(), // CONST OraText *str,
347 str.length(), // ub4 str_length,
348 NULL, // CONST OraText *fmt,
349 0, // ub4 fmt_length,
350 NULL, // CONST OraText *nls_params,
351 0, // ub4 nls_p_length,
352 &__data.num // OCINumber *number
353 );
354 if (status != OCI_SUCCESS) {
355 __SET_ERROR(SQL::eServerError, status, pError);
356 return false;
357 }
358 }
359 #endif
360 else {
362 return false;
363 }
364 OciData::__value = &__data;
365 OciData::__valueSize = sizeof(OCINumber);
366 OciData::__dataType = SQLT_VNU;
368 break;
369 }
370 case SQL::typeFloat: {
371 if (_size <= sizeof(double)) {
372 status = ::OCINumberFromReal(
373 pError, // OCIError *err,
374 (CONST dvoid*)_pv, // CONST dvoid *rnum,
375 _size, // uword rnum_length,
376 &__data.num // OCINumber *number
377 );
378 if (status != OCI_SUCCESS) {
379 __SET_ERROR(SQL::eServerError, status, pError);
380 return false;
381 }
382 }
383 else {
385 return false;
386 }
387 OciData::__value = &__data;
388 OciData::__valueSize = sizeof(OCINumber);
389 OciData::__dataType = SQLT_VNU;
391 break;
392 }
393 case SQL::typeDate: {
394 if (_size == sizeof(SQL::Date)) {
395 const SQL::Date* p = (const SQL::Date*)_pv;
397 ts.year = p->year;
398 ts.month = p->month;
399 ts.day = p->day;
400 ts.hour = ts.min = ts.sec = 0;
401 ts.frac = 0;
402 ts.tzoff = INT16_MIN;
404 return false;
405 }
406 else {
408 return false;
409 }
410 break;
411 }
412 case SQL::typeTime: {
413 // Oracle에서 DATE, TIMESTAMP 모두 시간만 저장할 수 없다.
415 return false;
416 }
417 case SQL::typeTimeStamp: {
418 if (_size == sizeof(SQL::TimeStamp)) {
419 if (!setTimeStamp((const SQL::TimeStamp*)_pv, _size, _assignType))
420 return false;
421 }
422 else {
424 return false;
425 }
426 break;
427 }
428 case SQL::typeInterval: {
429 if (_size == sizeof(SQL::Interval)) {
430 if (!setInterval((const SQL::Interval*)_pv, _size, _assignType))
431 return false;
432 }
433 else {
435 return false;
436 }
437 break;
438 }
439 case SQL::typeText: {
440 if (_assignType == SQL::typeNumeric) {
441 status = ::OCINumberFromText(
442 pError, // OCIError *err,
443 (CONST OraText*)_pv, // CONST OraText *str,
444 _size, // ub4 str_length,
445 NULL, // CONST OraText *fmt,
446 0, // ub4 fmt_length,
447 NULL, // CONST OraText *nls_params,
448 0, // ub4 nls_p_length,
449 &__data.num // OCINumber *number
450 );
451 if (status != OCI_SUCCESS) {
452 __SET_ERROR(SQL::eServerError, status, pError);
453 return false;
454 }
455 OciData::__value = &__data;
456 OciData::__valueSize = sizeof(OCINumber);
457 OciData::__dataType = SQLT_VNU;
459 break;
460 }
461 }
462 case SQL::typeBinary: {
463 switch (_assignType) {
464 case SQL::typeText: {
465 OciData::__dataType = SQLT_CHR;
467 break;
468 }
469 case SQL::typeBinary: {
470 OciData::__dataType = SQLT_BIN;
472 break;
473 }
474 case SQL::typeLongText: {
475 OciData::__dataType = SQLT_LNG;
477 break;
478 }
479 case SQL::typeLongBinary: {
480 OciData::__dataType = SQLT_LBI;
482 break;
483 }
484 default: {
486 return false;
487 }
488 }
489 OciData::__value = _pv;
490 OciData::__valueSize = _size;
491 break;
492 }
494 switch (_assignType) {
495 case SQL::typeText: {
496 OciData::__dataType = SQLT_CHR;
498 break;
499 }
500 case SQL::typeBinary: {
501 OciData::__dataType = SQLT_BIN;
503 break;
504 }
505 case SQL::typeLongText: {
506 OciData::__dataType = SQLT_LNG;
508 break;
509 }
510 case SQL::typeLongBinary: {
511 OciData::__dataType = SQLT_LBI;
513 break;
514 }
515 default: {
517 return false;
518 }
519 }
521 if (_size > INT32_MAX)
523 else
524 OciData::__valueSize = _size;
525 __inputStream = (InputStream*)_pv;
526 break;
527 }
528 default: {
530 return false;
531 }
532 }
533
534 Param::__dataType = _assignType;
535 __inputIndicator = 0;
536
537 return true;
538}
539
540inline int16_t __ABS(int16_t n)
541{
542 return n < 0 ? -n : n;
543}
544
546 const SQL::TimeStamp* _pv,
547 size_t _size,
548 SQL::DataType _assignType
549 )
550{
551 OciConnection* _conn = conn();
552 sword status = OCI_SUCCESS;
553
554 if (OciData::__descType == 0) {
556
557 ub2 dataType = SQLT_TIMESTAMP;
558 ub4 descType = OCI_DTYPE_TIMESTAMP;
559 if (_assignType == SQL::typeTimeStampTz) {
560 dataType = SQLT_TIMESTAMP_TZ;
561 descType = OCI_DTYPE_TIMESTAMP_TZ;
562 }
563
564 status = _conn->OCIDescriptorAlloc(
565 &(__data.desc),
566 descType
567 );
568 if (status != OCI_SUCCESS) {
570 return false;
571 }
572
573 OciData::__descType = descType;
574 OciData::__dataType = dataType;
576 }
577
578 ByteString strTz;
579 OraText* pTz = NULL;
580 size_t nTzLen = 0;
581 if (_assignType == SQL::typeTimeStampTz) {
582 strTz = ByteString::format(
583 // 6,
584 "%02d:%02d",
585 _pv->tzoff / 60,
586 __ABS(_pv->tzoff % 60)
587 );
588 pTz = (OraText*)strTz.data();
589 nTzLen = strTz.length();
590 }
591
592 OCISession* pSession = _conn->sessionHandle();
593 OCIError* pError = _conn->errorHandle();
594
595 status = ::OCIDateTimeConstruct(
596 pSession, // dvoid *hndl,
597 pError, // OCIError *err,
598 (OCIDateTime*)__data.desc, // OCIDateTime *datetime,
599 _pv->year, // sb2 year,
600 _pv->month, // ub1 month,
601 _pv->day, // ub1 day,
602 _pv->hour, // ub1 hour,
603 _pv->min, // ub1 min,
604 _pv->sec, // ub1 sec,
605 _pv->frac, // ub4 fsec,
606 pTz, // OraText *timezone,
607 nTzLen // size_t timezone_length
608 );
609 if (status != OCI_SUCCESS) {
611 return false;
612 }
613
614 OciData::__value = &__data;
615 OciData::__valueSize = sizeof(OCIDateTime*);
616
617 return true;
618}
619
621 const SQL::Interval* _pv,
622 size_t _size,
623 SQL::DataType _assignType
624 )
625{
626 OciConnection* _conn = conn();
627 sword status = OCI_SUCCESS;
628
629 if (OciData::__descType == 0) {
631
632 ub2 dataType = SQLT_INTERVAL_DS;
633 ub4 descType = OCI_DTYPE_INTERVAL_DS;
634 if (_assignType == SQL::typeIntervalYm) {
635 dataType = SQLT_INTERVAL_YM;
636 descType = OCI_DTYPE_INTERVAL_YM;
637 }
638
639 status = _conn->OCIDescriptorAlloc(
640 &(__data.desc),
641 descType
642 );
643 if (status != OCI_SUCCESS) {
645 return false;
646 }
647
648 OciData::__descType = descType;
649 OciData::__dataType = dataType;
651 }
652
653 OCISession* pSession = _conn->sessionHandle();
654 OCIError* pError = _conn->errorHandle();
655
656 if (OciData::__dataType == SQLT_INTERVAL_YM) {
657 // set zero
658 // 이부분이 빠지면 Query::execute에서
659 status = ::OCIIntervalFromText(
660 pSession, // dvoid *hndl,
661 pError, // OCIError *err,
662 (CONST OraText*)"0-0", // CONST OraText *inpstring,
663 3, // size_t str_len,
664 (OCIInterval*)__data.desc // OCIInterval *result
665 );
666 if (status == OCI_SUCCESS)
667 status = ::OCIIntervalSetYearMonth(
668 pSession, // dvoid *hndl,
669 pError, // OCIError *err,
670 _pv->years, // sb4 yr,
671 _pv->months, // sb4 mnth,
672 (OCIInterval*)__data.desc // OCIInterval *result
673 );
674 }
675 else {
676 status = ::OCIIntervalFromText(
677 pSession, // dvoid *hndl,
678 pError, // OCIError *err,
679 (CONST OraText*)"0 00:00:00", // CONST OraText *inpstring,
680 10, // size_t str_len,
681 (OCIInterval*)__data.desc // OCIInterval *result
682 );
683 if (status == OCI_SUCCESS)
684 status = ::OCIIntervalSetDaySecond(
685 pSession, // dvoid *hndl,
686 pError, // OCIError *err,
687 _pv->days, // sb4 dy,
688 _pv->hours, // sb4 hr,
689 _pv->mins, // sb4 mm,
690 _pv->secs, // sb4 ss,
691 _pv->fracs, // sb4 fsec,
692 (OCIInterval*)__data.desc // OCIInterval *result
693 );
694 }
695#if defined(__DCL_DEBUG) && 1
696 if (status == OCI_SUCCESS) {
697 ub4 valid = 0;
698 status = ::OCIIntervalCheck(
699 pSession, // dvoid *hndl,
700 pError, // OCIError *err,
701 (CONST OCIInterval*)__data.desc, // CONST OCIInterval *interval,
702 &valid // ub4 *valid
703 );
704 }
705#endif
706
707 if (status != OCI_SUCCESS) {
709 return false;
710 }
711
712 OciData::__value = &__data;
713 OciData::__valueSize = sizeof(OCIInterval*);
714
715 return true;
716}
717
719{
720 sword status = OCI_SUCCESS;
721 OciConnection* pConnection = conn();
722 OCIError* pError = pConnection->errorHandle();
723 OCIStmt* pStmt = query()->stmtHandle();
724
725 if (OciData::__dataType == 0) {
726 // then out bind only param
729 __DCL_ASSERT(__buffer == NULL);
730 }
731
732 // __DCL_TRACE3_N("%s, %d, %p\n", Param::__name.data(),
733 // OciData::__valueSize, OciData::__value);
734 status = ::OCIBindByPos(
735 pStmt, // OCIStmt *stmtp,
736 &__bind, // OCIBind **bindp,
737 pError, // OCIError *errhp,
738 OciData::__position, // ub4 position,
739 NULL, // dvoid *valuep,
740 OciData::__valueSize, // sb4 value_sz,
741 OciData::__dataType, // ub2 dty,
742 &__inputIndicator, // dvoid *indp,
743 NULL, // ub2 *alenp,
744 &(OciData::__returnCode), // ub2 *rcodep,
745 0, // ub4 maxarr_len,
746 NULL, // ub4 *curelep,
747 OciData::__dynamicMode // ub4 mode
748 );
749 if (status != OCI_SUCCESS) {
750 __SET_ERROR(SQL::eServerError, status, pError);
751 conn()->setErrorEx(ByteString::format("position[%d]", OciData::__position));
752 return false;
753 }
754 __DCL_ASSERT(__bind != NULL); // bindDynamic은 bindByPos 이후에
755 if (OciData::__dynamicMode == OCI_DATA_AT_EXEC) {
756 status = ::OCIBindDynamic(
757 __bind, // OCIBind *bindp,
758 pError, // OCIError *errhp,
759 this, // dvoid *ictxp,
761 this, // dvoid *octxp
763 );
764 if (status != OCI_SUCCESS) {
765 __SET_ERROR(SQL::eServerError, status, pError);
766 conn()->setErrorEx(ByteString::format("position[%d]", OciData::__position));
767 return false;
768 }
769 }
770
771 return true;
772}
773
775 dvoid *ictxp,
776 OCIBind *bindp,
777 ub4 iter,
778 ub4 index,
779 dvoid **bufpp,
780 ub4 *alenp,
781 ub1 *piecep,
782 dvoid **indpp
783 )
784{
785 return ((OciParam*)ictxp)->onCallbackInBind(
786 bindp,
787 iter,
788 index,
789 bufpp,
790 alenp,
791 piecep,
792 indpp
793 );
794}
795
797 dvoid *octxp,
798 OCIBind *bindp,
799 ub4 iter,
800 ub4 index,
801 dvoid **bufpp,
802 ub4 **alenpp,
803 ub1 *piecep,
804 dvoid **indpp,
805 ub2 **rcodepp
806 )
807{
808 return ((OciParam*)octxp)->onCallbackOutBind(
809 bindp,
810 iter,
811 index,
812 bufpp,
813 alenpp,
814 piecep,
815 indpp,
816 rcodepp
817 );
818}
819
820inline size_t __MIN(size_t x, size_t y)
821{
822 return x < y ? x : y;
823}
824
826 OCIBind* pBind,
827 ub4 nIterator,
828 ub4 _index,
829 dvoid** ppvBuffer,
830 ub4* pnActualLength,
831 ub1* pnPiece,
832 dvoid** ppvIndicator
833 )
834{
835
836//#ifdef __DCL_DEBUG
837// switch(*pnPiece)
838// {
839// case OCI_ONE_PIECE :
840// __DCL_TRACE1_N(L"OCI_ONE_PIECE: %s\n", UTF8Decoder::decode(Param::__name).data());
841// break;
842// case OCI_FIRST_PIECE :
843// __DCL_TRACE1_N(L"OCI_FIRST_PIECE: %s\n", UTF8Decoder::decode(Param::__name).data());
844// break;
845// case OCI_NEXT_PIECE :
846// __DCL_TRACE1_N(L"OCI_NEXT_PIECE: %s\n", UTF8Decoder::decode(Param::__name).data());
847// break;
848// case OCI_LAST_PIECE :
849// __DCL_TRACE1_N(L"OCI_LAST_PIECE: %s\n", UTF8Decoder::decode(Param::__name).data());
850// }
851//#endif
852
853 if (__inputIndicator == -1) {
854 *ppvBuffer = NULL;
855 *pnActualLength = 0;
856 *pnPiece = OCI_ONE_PIECE;
857 *ppvIndicator = &__inputIndicator;
858 return OCI_CONTINUE;
859 }
860
861 if (__inputStream) {
863 || OciData::__dataType == SQLT_BIN
864 || OciData::__dataType == SQLT_LNG
865 || OciData::__dataType == SQLT_LBI);
866
867 if (!__buffer) {
868 __buffer = malloc(DYNAMIC_BUFFER_SIZE);
869 if (!__buffer) {
871 return OCI_ERROR;
872 }
873 }
874
875 __DCL_ASSERT(__buffer != NULL);
876
877 size_t nRead = __MIN((size_t)OciData::__valueSize, DYNAMIC_BUFFER_SIZE);
878
879 if (nRead) {
880 try {
881 nRead = __inputStream->read(__buffer, nRead);
882 }
883 catch(IOException* e) {
884 conn()->setErrorEx(UTF8Encoder::encode(e->toStringAll()));
885 e->destroy();
886 return OCI_ERROR;
887 }
888 }
889
890 if (*pnPiece == OCI_FIRST_PIECE) {
891 if (nRead == (size_t)OciData::__valueSize)
892 *pnPiece = OCI_ONE_PIECE;
893 }
894 else {
895 // OCI_NEXT_PIECE
896 if (nRead == 0 || nRead == (size_t)OciData::__valueSize)
897 *pnPiece = OCI_LAST_PIECE;
898 }
899
900 OciData::__valueSize -= nRead;
901
902 *ppvBuffer = __buffer;
903 *pnActualLength = nRead;
904 *ppvIndicator = NULL;
905 }
906 else {
908 // 입력이 TIMESTAMP와 같은 디스크립터일 경우 버퍼에 이들의 값을
909 // 넣어 준다.
910 *ppvBuffer = __data.desc;
911 }
912 else {
913 // 나머지 경우 OciData::m_pValue는
914 // 외부에서 받은 char*, byte_t* 그리고 &OciParam::__data 이다.
915 *ppvBuffer = OciData::__value;
916 }
917 *pnActualLength = OciData::__valueSize;
918 *pnPiece = OCI_ONE_PIECE;
919 *ppvIndicator = &__inputIndicator;
920 }
921
922 return OCI_CONTINUE;
923}
924
926 OCIBind* pBind,
927 ub4 nIterator,
928 ub4 _index,
929 dvoid** ppvBuffer,
930 ub4** ppnActualLength,
931 ub1* pnPiece,
932 dvoid** ppvIndicator,
933 ub2** ppnReturnCode
934 )
935{
936 __DCL_ASSERT(OciData::__dynamicMode == OCI_DATA_AT_EXEC);
937 /*
938 if (_index == 0) {
939 ub4 nRows = 0;
940 ub4 _size = 0;
941
942 sword status = ::OCIAttrGet(
943 __bind,
944 OCI_HTYPE_BIND,
945 &nRows,
946 &_size,
947 OCI_ATTR_ROWS_RETURNED,
948 query()->connection()->errorHandle());
949 if (status != OCI_SUCCESS) {
950 return OCI_ERROR;
951 }
952 }
953 */
954/*
955#ifdef __DCL_DEBUG
956 switch(*pnPiece) {
957 case OCI_ONE_PIECE :
958 __DCL_TRACE1_N("OCI_ONE_PIECE: %s\n", Param::__name.data());
959 break;
960 case OCI_FIRST_PIECE :
961 __DCL_TRACE1_N("OCI_FIRST_PIECE: %s\n", Param::__name.data());
962 break;
963 case OCI_NEXT_PIECE :
964 __DCL_TRACE1_N("OCI_NEXT_PIECE: %s\n", Param::__name.data());
965 break;
966 case OCI_LAST_PIECE :
967 __DCL_TRACE1_N("OCI_LAST_PIECE: %s\n", Param::__name.data());
968 }
969#endif
970*/
971 if (OciData::__dataType == SQLT_CHR
972 || OciData::__dataType == SQLT_BIN
973 || OciData::__dataType == SQLT_LNG
974 || OciData::__dataType == SQLT_LBI) {
975 if (*pnPiece == OCI_ONE_PIECE)
976 *pnPiece = OCI_FIRST_PIECE;
977
978 if (*pnPiece == OCI_FIRST_PIECE) {
979 if (!__buffer) {
980 __buffer = malloc(DYNAMIC_BUFFER_SIZE);
981 if (!__buffer) {
983 return OCI_ERROR;
984 }
985 }
986
987 OciData::__value = __buffer;
989 __bytesOutput->reset();
990 }
991 else {
992 // 두번째 PIECE 부터는 이전 데이터를 내부 스트림에 보관한다.
997 return OCI_ERROR;
998 }
999 }
1000
1002 try {
1006 );
1007 }
1008 catch(IOException* e) {
1009 conn()->setErrorEx(
1010 UTF8Encoder::encode(e->toStringAll())
1011 );
1012 e->destroy();
1013 return OCI_ERROR;
1014 }
1015 }
1016
1019
1020 *ppvBuffer = OciData::__value;
1021 *ppnActualLength = &(OciData::__callbackActualLength);
1022 *ppvIndicator = &(OciData::__indicator);
1023 *ppnReturnCode = &(OciData::__returnCode);
1024 }
1025 else {
1026 // 버퍼가 OCIDateTime*, OCILogLocator*, OCIRowid* 와 같은
1027 // void*의 디스크립터 일 경우 ppvBuffer에는 이들 디스크립터의
1028 // 값을 넣어 주어야 한다.
1029 // 그러나, OciData::getData에서는 OciData::m_pValue를 사용하여
1030 // 값을 얻기 때문에 이들의 주소를 할당해야 한다.
1031 // OCIDateTime의 경우 *(OCIDateTime**)OciData::__value 와 같이 사용된다.
1032 //
1033 // OCINumber, OCIDate와 같은 경우 이들의 포인터를 할당한다.
1034 if (OciData::__descType) {
1035 OciData::__value = &__data.desc;
1036 OciData::__callbackActualLength = sizeof(void*);
1037 *ppvBuffer = __data.desc;
1038 }
1039 else {
1040 OciData::__value = &__data;
1042 *ppvBuffer = &__data;
1043 }
1045
1046 *pnPiece = OCI_ONE_PIECE;
1047 *ppnActualLength = &(OciData::__callbackActualLength);//NULL;
1048 *ppvIndicator = &(OciData::__indicator);
1049 *ppnReturnCode = &(OciData::__returnCode);
1050 }
1051
1052 return OCI_CONTINUE;
1053}
1054
1055__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:340
#define INT32_MAX
Definition Config.h:318
#define _CONST
Definition Config.h:353
#define UINT32_MAX
Definition Config.h:323
#define INT16_MIN
Definition Config.h:312
#define __ABS(n)
Definition MyParam.cpp:143
#define __DCL_VERIFY(expr)
Definition Object.h:373
#define __DCL_ASSERT(expr)
Definition Object.h:371
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:228
#define __T(str)
Definition Object.h:44
#define DYNAMIC_BUFFER_SIZE
Definition OciData.h:11
size_t __MIN(size_t x, size_t y)
Definition OciParam.cpp:820
#define __SET_ERROR(_errorCode)
Definition SQLCore.cpp:153
void CharsetConvertException *size_t n
Definition SQLField.cpp:254
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
static ByteString toByteString(int64_t _n, unsigned _base=10)
Definition Numeric.cpp:581
sword OCIDescriptorAlloc(void **ppDescriptorHandle, ub4 nDescriptorType, size_t xtramem_sz=0, void **ppvUserMem=NULL)
OCIError * errorHandle() const
void setErrorEx(const ByteString &_message)
OCISession * sessionHandle() const
sb2 __indicator
Definition OciData.h:24
bool getData(void *_pv, size_t *_size, SQL::DataType _dataType)
Definition OciData.cpp:202
ub2 __dataType
Definition OciData.h:21
sb4 __valueSize
Definition OciData.h:23
OciQuery * __queryHandle
Definition OciData.h:16
bool onAfterFetch()
Definition OciData.cpp:83
ub4 __dynamicMode
Definition OciData.h:19
static const wchar_t * dataTypeName(ub2 _dataType)
Definition OciData.cpp:872
bool getDataSize(size_t *_size, bool _maxSize)
Definition OciData.cpp:172
ub4 __position
Definition OciData.h:17
ub2 __returnCode
Definition OciData.h:27
ub4 __callbackActualLength
Definition OciData.h:26
size_t __maxDataSize
Definition OciData.h:31
OciConnection * conn() const
Definition OciData.h:64
ub4 __descType
Definition OciData.h:18
void * __value
Definition OciData.h:22
BytesOutputStream * __bytesOutput
Definition OciData.h:29
virtual bool __getDataSize(size_t *_size, bool _maxSize)
Definition OciParam.cpp:255
bool setTimeStamp(const SQL::TimeStamp *_pv, size_t _size, SQL::DataType _assignType)
Definition OciParam.cpp:545
sb4 onCallbackInBind(OCIBind *pBind, ub4 nIterator, ub4 _index, dvoid **ppvBuffer, ub4 *pnActualLength, ub1 *pnPiece, dvoid **ppvIndicator)
Definition OciParam.cpp:825
virtual bool isNull() const
Definition OciParam.cpp:245
static sb4 CallbackInBind(dvoid *ictxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp)
Definition OciParam.cpp:774
bool init(SQL::Query *_query, ub4 _position)
Definition OciParam.cpp:79
virtual bool __setDataType(SQL::DataType _dataType)
Definition OciParam.cpp:100
sb4 onCallbackOutBind(OCIBind *pBind, ub4 nIterator, ub4 _index, dvoid **ppvBuffer, ub4 **ppnActualLength, ub1 *pnPiece, dvoid **ppvIndicator, ub2 **ppnReturnCode)
Definition OciParam.cpp:925
virtual bool __getData(void *_pv, size_t *_size, SQL::DataType _dataType)
Definition OciParam.cpp:263
virtual void setNull()
Definition OciParam.cpp:272
virtual bool __setData(_CONST void *_pv, size_t _size, SQL::DataType _dataType, SQL::DataType _assignType)
Definition OciParam.cpp:283
OciQuery * query() const
Definition OciParam.h:27
bool setInterval(const SQL::Interval *_pv, size_t _size, SQL::DataType _assignType)
Definition OciParam.cpp:620
virtual const wchar_t * serverDataTypeName() const
Definition OciParam.cpp:250
bool onAfterExecute()
Definition OciParam.cpp:90
static sb4 CallbackOutBind(dvoid *octxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp)
Definition OciParam.cpp:796
virtual ~OciParam()
Definition OciParam.cpp:61
bool doBind()
Definition OciParam.cpp:718
ub2 _dataType() const
Definition OciParam.h:29
DataType
Definition SQLCore.h:62
@ typeBinary
Definition SQLCore.h:77
@ typeClob
Definition SQLCore.h:80
@ typeNumeric
Definition SQLCore.h:67
@ typeTime
Definition SQLCore.h:69
@ typeLongBinary
Definition SQLCore.h:79
@ typeUInteger
Definition SQLCore.h:65
@ typeUnknown
Definition SQLCore.h:63
@ typeTimeStamp
Definition SQLCore.h:71
@ typeBlob
Definition SQLCore.h:81
@ typeInputStream
Definition SQLCore.h:84
@ typeTimeStampTz
Definition SQLCore.h:72
@ typeInterval
Definition SQLCore.h:73
@ typeIntervalDs
Definition SQLCore.h:75
@ typeDate
Definition SQLCore.h:68
@ typeText
Definition SQLCore.h:76
@ typeFloat
Definition SQLCore.h:66
@ typeInteger
Definition SQLCore.h:64
@ typeIntervalYm
Definition SQLCore.h:74
@ typeLongText
Definition SQLCore.h:78
@ eOutOfMemory
Definition SQLCore.h:24
@ eNotSupportDataType
Definition SQLCore.h:48
@ eServerError
Definition SQLCore.h:21
@ eInvalidDataSize
Definition SQLCore.h:57
@ eInvalidDataType
Definition SQLCore.h:49
static ByteString toByteString(uint64_t _u, unsigned _base=10)
Definition Numeric.cpp:680
size_t __MIN(size_t x, size_t y)
Definition size_t.h:27
int16_t year
Definition SQLCore.h:97
uint8_t month
Definition SQLCore.h:98
uint8_t day
Definition SQLCore.h:99
int32_t years
Definition SQLCore.h:127
int32_t days
Definition SQLCore.h:129
int8_t hours
Definition SQLCore.h:130
int8_t mins
Definition SQLCore.h:131
int32_t fracs
Definition SQLCore.h:133
int8_t months
Definition SQLCore.h:128
int8_t secs
Definition SQLCore.h:132
uint32_t frac
Definition SQLCore.h:119
int16_t tzoff
Definition SQLCore.h:120
uint8_t min
Definition SQLCore.h:117
uint8_t sec
Definition SQLCore.h:118
uint8_t hour
Definition SQLCore.h:116
uint8_t day
Definition SQLCore.h:115
int16_t year
Definition SQLCore.h:113
uint8_t month
Definition SQLCore.h:114