DCL 4.0
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 switch(_dataType) {
105 case SQL::typeInteger :
106 case SQL::typeUInteger :
107 case SQL::typeFloat :
109 break;
110 case SQL::typeDate :
112 default :
113 ;
114 }
115
116 if (Param::__dataType != SQL::typeUnknown) {
117 if (Param::__dataType != _dataType) {
119 return false;
120 }
121 return true;
122 }
123
124 OciConnection* pConnection = conn();
125 sword status = OCI_SUCCESS;
126
127 switch(_dataType) {
128 //case SQL::typeInteger :
129 //case SQL::typeUInteger :
130 //case SQL::typeFloat :
131 case SQL::typeNumeric: {
132 OciData::__valueSize = sizeof(OCINumber);
133 OciData::__dataType = SQLT_VNU;
135 break;
136 }
137 case SQL::typeTime: {
138 // Oracle에서 DATE, TIMESTAMP은 모두 TIME만 저장할 수 없다.
140 break;
141 }
142 //case SQL::typeDate :
143 case SQL::typeTimeStamp :
145 ub2 dataType = SQLT_TIMESTAMP;
146 ub4 nDescType = OCI_DTYPE_TIMESTAMP;
148 dataType = SQLT_TIMESTAMP_TZ;
149 nDescType = OCI_DTYPE_TIMESTAMP_TZ;
150 }
151
152 status = pConnection->OCIDescriptorAlloc(
153 &(__data.desc),
154 nDescType
155 );
156 if (status != OCI_SUCCESS) {
158 return false;
159 }
160 OciData::__descType = nDescType;
161 OciData::__valueSize = sizeof(OCIDateTime*);
162 OciData::__dataType = dataType;
164 break;
165 }
166 case SQL::typeInterval :
168 case SQL::typeIntervalDs: {
169 ub2 dataType = SQLT_INTERVAL_DS;
170 ub4 nDescType = OCI_DTYPE_INTERVAL_DS;
172 dataType = SQLT_INTERVAL_YM;
173 nDescType = OCI_DTYPE_INTERVAL_YM;
174 }
175
176 status = pConnection->OCIDescriptorAlloc(
177 &(__data.desc),
178 OCI_DTYPE_INTERVAL_DS
179 );
180 if (status != OCI_SUCCESS) {
182 return false;
183 }
184 OciData::__descType = nDescType;
185 OciData::__valueSize = sizeof(OCIInterval*);
186 OciData::__dataType = dataType;
188 break;
189 }
190 case SQL::typeText: {
192 OciData::__dataType = SQLT_CHR;
193 OciData::__maxDataSize = 4000; // AFC ==> 2000
194 break;
195 }
196 case SQL::typeBinary: {
198 OciData::__dataType = SQLT_BIN;
200 break;
201 }
202 case SQL::typeLongText: {
204 OciData::__dataType = SQLT_LNG;
206 break;
207 }
208 case SQL::typeLongBinary: {
210 OciData::__dataType = SQLT_LBI;
212 break;
213 }
214 case SQL::typeClob: {
215 status = pConnection->OCIDescriptorAlloc(
216 &(__data.desc),
217 OCI_DTYPE_LOB
218 );
219 if (status != OCI_SUCCESS) {
221 return false;
222 }
223 OciData::__descType = OCI_DTYPE_LOB;
224 OciData::__valueSize = sizeof(OCILobLocator*);
225 OciData::__dataType = SQLT_CLOB;
227 break;
228 }
229 case SQL::typeBlob: {
230 status = pConnection->OCIDescriptorAlloc(
231 &(__data.desc),
232 OCI_DTYPE_LOB
233 );
234 if (status != OCI_SUCCESS) {
236 return false;
237 }
238 OciData::__descType = OCI_DTYPE_LOB;
239 OciData::__valueSize = sizeof(OCILobLocator*);
240 OciData::__dataType = SQLT_BLOB;
242 break;
243 }
244 default: {
246 return false;
247 }
248 }
249
250 Param::__dataType = _dataType;
251 return true;
252}
253
255{
256 return OciData::__indicator == -1;
257}
258
259const wchar_t* OciParam::serverDataTypeName() const
260{
262}
263
265 size_t* _size,
266 bool _maxSize
267 )
268{
269 return OciData::getDataSize(_size, _maxSize);
270}
271
273 void* _pv,
274 size_t* _size, // IN, OUT
276 )
277{
278 return OciData::getData(_pv, _size, _dataType);
279}
280
282{
283 // FIX 2025-02-10 See 753 OCIBindByPos
284 Param::__dataType = SQL::typeUnknown;
285 OciData::__dataType = SQLT_CHR;
289 __inputIndicator = -1;
290}
291
293 _CONST void* _pv,
294 size_t _size,
296 SQL::DataType _assignType
297 )
298{
299 switch(_assignType) {
300 case SQL::typeInteger :
301 case SQL::typeUInteger :
302 case SQL::typeFloat :
303 _assignType = SQL::typeNumeric;
304 break;
305 case SQL::typeDate :
306 _assignType = SQL::typeTimeStamp;
307 default :
308 ;
309 }
310
311 if (Param::__dataType != SQL::typeUnknown) {
312 if (Param::__dataType != _assignType) {
314 return false;
315 }
316 }
317
318 OCIError* pError = conn()->errorHandle();
319 sword status = OCI_SUCCESS;
320
321 switch(_dataType) {
322 case SQL::typeInteger :
323 case SQL::typeUInteger: {
324 if (_size <= sizeof(int64_t /* 2025-02-03 월 int32_t */)) {
325 uword sign = OCI_NUMBER_SIGNED;
327 sign = OCI_NUMBER_UNSIGNED;
328
329 status = ::OCINumberFromInt(
330 pError, // OCIError *err,
331 (CONST dvoid*)_pv, // CONST dvoid *inum,
332 _size, // uword inum_length,
333 sign, // uword inum_s_flag,
334 &__data.num // OCINumber *number
335 );
336 if (status != OCI_SUCCESS) {
337 __SET_ERROR(SQL::eServerError, status, pError);
338 return false;
339 }
340 }
341 #if 0 // 2025-02-03 월
342 else if (_size == sizeof(int64_t)) {
343 ByteString str;
345 str = Int64::toByteString(*(int64_t*)_pv, 10);
346 else
347 str = UInt64::toByteString(*(uint64_t*)_pv, 10);
348
349 status = ::OCINumberFromText(
350 pError, // OCIError *err,
351 (CONST OraText*)str.data(), // CONST OraText *str,
352 str.length(), // ub4 str_length,
353 NULL, // CONST OraText *fmt,
354 0, // ub4 fmt_length,
355 NULL, // CONST OraText *nls_params,
356 0, // ub4 nls_p_length,
357 &__data.num // OCINumber *number
358 );
359 if (status != OCI_SUCCESS) {
360 __SET_ERROR(SQL::eServerError, status, pError);
361 return false;
362 }
363 }
364 #endif
365 else {
367 return false;
368 }
369 OciData::__value = &__data;
370 OciData::__valueSize = sizeof(OCINumber);
371 OciData::__dataType = SQLT_VNU;
373 break;
374 }
375 case SQL::typeFloat: {
376 if (_size <= sizeof(double)) {
377 status = ::OCINumberFromReal(
378 pError, // OCIError *err,
379 (CONST dvoid*)_pv, // CONST dvoid *rnum,
380 _size, // uword rnum_length,
381 &__data.num // OCINumber *number
382 );
383 if (status != OCI_SUCCESS) {
384 __SET_ERROR(SQL::eServerError, status, pError);
385 return false;
386 }
387 }
388 else {
390 return false;
391 }
392 OciData::__value = &__data;
393 OciData::__valueSize = sizeof(OCINumber);
394 OciData::__dataType = SQLT_VNU;
396 break;
397 }
398 case SQL::typeDate: {
399 if (_size == sizeof(SQL::Date)) {
400 const SQL::Date* p = (const SQL::Date*)_pv;
402 ts.nYear = p->nYear;
403 ts.nMonth = p->nMonth;
404 ts.nDay = p->nDay;
405 ts.nHour = ts.nMin = ts.nSec = 0;
406 ts.nFrac = 0;
407 ts.nTzMin = 0;
409 return false;
410 }
411 else {
413 return false;
414 }
415 break;
416 }
417 case SQL::typeTime: {
418 // Oracle에서 DATE, TIMESTAMP 모두 시간만 저장할 수 없다.
420 return false;
421 }
422 case SQL::typeTimeStamp :
424 if (_size == sizeof(SQL::TimeStamp)) {
425 if (!setTimeStamp((const SQL::TimeStamp*)_pv, _size, _assignType))
426 return false;
427 }
428 else {
430 return false;
431 }
432 break;
433 }
436 case SQL::typeIntervalDs: {
437 if (_size == sizeof(SQL::Interval)) {
438 if (!setInterval((const SQL::Interval*)_pv, _size, _assignType))
439 return false;
440 }
441 else {
443 return false;
444 }
445 break;
446 }
447 case SQL::typeText: {
448 if (_assignType == SQL::typeNumeric) {
449 status = ::OCINumberFromText(
450 pError, // OCIError *err,
451 (CONST OraText*)_pv, // CONST OraText *str,
452 _size, // ub4 str_length,
453 NULL, // CONST OraText *fmt,
454 0, // ub4 fmt_length,
455 NULL, // CONST OraText *nls_params,
456 0, // ub4 nls_p_length,
457 &__data.num // OCINumber *number
458 );
459 if (status != OCI_SUCCESS) {
460 __SET_ERROR(SQL::eServerError, status, pError);
461 return false;
462 }
463 OciData::__value = &__data;
464 OciData::__valueSize = sizeof(OCINumber);
465 OciData::__dataType = SQLT_VNU;
467 break;
468 }
469 }
470 case SQL::typeLongText :
471 case SQL::typeBinary :
472 case SQL::typeLongBinary: {
473 switch (_assignType) {
474 case SQL::typeText: {
475 OciData::__dataType = SQLT_CHR;
477 break;
478 }
479 case SQL::typeBinary: {
480 OciData::__dataType = SQLT_BIN;
482 break;
483 }
484 case SQL::typeLongText: {
485 OciData::__dataType = SQLT_LNG;
487 break;
488 }
489 case SQL::typeLongBinary: {
490 OciData::__dataType = SQLT_LBI;
492 break;
493 }
494 default: {
496 return false;
497 }
498 }
499 OciData::__value = _pv;
500 OciData::__valueSize = _size;
501 break;
502 }
504 switch (_assignType) {
505 case SQL::typeText: {
506 OciData::__dataType = SQLT_CHR;
508 break;
509 }
510 case SQL::typeBinary: {
511 OciData::__dataType = SQLT_BIN;
513 break;
514 }
515 case SQL::typeLongText: {
516 OciData::__dataType = SQLT_LNG;
518 break;
519 }
520 case SQL::typeLongBinary: {
521 OciData::__dataType = SQLT_LBI;
523 break;
524 }
525 default: {
527 return false;
528 }
529 }
531 if (_size > INT32_MAX)
533 else
534 OciData::__valueSize = _size;
535 __inputStream = (InputStream*)_pv;
536 break;
537 }
538 default: {
540 return false;
541 }
542 }
543
544 Param::__dataType = _assignType;
545 __inputIndicator = 0;
546
547 return true;
548}
549
550inline int16_t __ABS(int16_t n)
551{
552 return n < 0 ? -n : n;
553}
554
556 const SQL::TimeStamp* _pv,
557 size_t _size,
558 SQL::DataType _assignType
559 )
560{
561 OciConnection* _conn = conn();
562 sword status = OCI_SUCCESS;
563
564 if (OciData::__descType == 0) {
566
567 ub2 dataType = SQLT_TIMESTAMP;
568 ub4 nDescType = OCI_DTYPE_TIMESTAMP;
569 if (_assignType == SQL::typeTimeStampTz) {
570 dataType = SQLT_TIMESTAMP_TZ;
571 nDescType = OCI_DTYPE_TIMESTAMP_TZ;
572 }
573
574 status = _conn->OCIDescriptorAlloc(
575 &(__data.desc),
576 nDescType
577 );
578 if (status != OCI_SUCCESS) {
580 return false;
581 }
582
583 OciData::__descType = nDescType;
584 OciData::__dataType = dataType;
586 }
587
588 ByteString strTz;
589 OraText* pTz = NULL;
590 size_t nTzLen = 0;
591 if (_assignType == SQL::typeTimeStampTz) {
592 strTz = ByteString::format(
593 // 6,
594 "%02d:%02d",
595 _pv->nTzMin / 60,
596 __ABS(_pv->nTzMin % 60)
597 );
598 pTz = (OraText*)strTz.data();
599 nTzLen = strTz.length();
600 }
601
602 OCISession* pSession = _conn->sessionHandle();
603 OCIError* pError = _conn->errorHandle();
604
605 status = ::OCIDateTimeConstruct(
606 pSession, // dvoid *hndl,
607 pError, // OCIError *err,
608 (OCIDateTime*)__data.desc, // OCIDateTime *datetime,
609 _pv->nYear, // sb2 year,
610 _pv->nMonth, // ub1 month,
611 _pv->nDay, // ub1 day,
612 _pv->nHour, // ub1 hour,
613 _pv->nMin, // ub1 min,
614 _pv->nSec, // ub1 sec,
615 _pv->nFrac, // ub4 fsec,
616 pTz, // OraText *timezone,
617 nTzLen // size_t timezone_length
618 );
619 if (status != OCI_SUCCESS) {
621 return false;
622 }
623
624 OciData::__value = &__data;
625 OciData::__valueSize = sizeof(OCIDateTime*);
626
627 return true;
628}
629
631 const SQL::Interval* _pv,
632 size_t _size,
633 SQL::DataType _assignType
634 )
635{
636 OciConnection* _conn = conn();
637 sword status = OCI_SUCCESS;
638
639 if (OciData::__descType == 0) {
641
642 ub2 dataType = SQLT_INTERVAL_DS;
643 ub4 nDescType = OCI_DTYPE_INTERVAL_DS;
644 if (_assignType == SQL::typeIntervalYm) {
645 dataType = SQLT_INTERVAL_YM;
646 nDescType = OCI_DTYPE_INTERVAL_YM;
647 }
648
649 status = _conn->OCIDescriptorAlloc(
650 &(__data.desc),
651 nDescType
652 );
653 if (status != OCI_SUCCESS) {
655 return false;
656 }
657
658 OciData::__descType = nDescType;
659 OciData::__dataType = dataType;
661 }
662
663 OCISession* pSession = _conn->sessionHandle();
664 OCIError* pError = _conn->errorHandle();
665
666 if (OciData::__dataType == SQLT_INTERVAL_YM) {
667 // set zero
668 // 이부분이 빠지면 Query::execute에서
669 status = ::OCIIntervalFromText(
670 pSession, // dvoid *hndl,
671 pError, // OCIError *err,
672 (CONST OraText*)"0-0", // CONST OraText *inpstring,
673 3, // size_t str_len,
674 (OCIInterval*)__data.desc // OCIInterval *result
675 );
676 if (status == OCI_SUCCESS)
677 status = ::OCIIntervalSetYearMonth(
678 pSession, // dvoid *hndl,
679 pError, // OCIError *err,
680 _pv->nYears, // sb4 yr,
681 _pv->nMonths, // sb4 mnth,
682 (OCIInterval*)__data.desc // OCIInterval *result
683 );
684 }
685 else {
686 status = ::OCIIntervalFromText(
687 pSession, // dvoid *hndl,
688 pError, // OCIError *err,
689 (CONST OraText*)"0 00:00:00", // CONST OraText *inpstring,
690 10, // size_t str_len,
691 (OCIInterval*)__data.desc // OCIInterval *result
692 );
693 if (status == OCI_SUCCESS)
694 status = ::OCIIntervalSetDaySecond(
695 pSession, // dvoid *hndl,
696 pError, // OCIError *err,
697 _pv->nDays, // sb4 dy,
698 _pv->nHours, // sb4 hr,
699 _pv->nMins, // sb4 mm,
700 _pv->nSecs, // sb4 ss,
701 _pv->nFracs, // sb4 fsec,
702 (OCIInterval*)__data.desc // OCIInterval *result
703 );
704 }
705#if defined(__DCL_DEBUG) && 1
706 if (status == OCI_SUCCESS) {
707 ub4 valid = 0;
708 status = ::OCIIntervalCheck(
709 pSession, // dvoid *hndl,
710 pError, // OCIError *err,
711 (CONST OCIInterval*)__data.desc, // CONST OCIInterval *interval,
712 &valid // ub4 *valid
713 );
714 }
715#endif
716
717 if (status != OCI_SUCCESS) {
719 return false;
720 }
721
722 OciData::__value = &__data;
723 OciData::__valueSize = sizeof(OCIInterval*);
724
725 return true;
726}
727
729{
730 sword status = OCI_SUCCESS;
731 OciConnection* pConnection = conn();
732 OCIError* pError = pConnection->errorHandle();
733 OCIStmt* pStmt = query()->stmtHandle();
734
735 if (OciData::__dataType == 0) {
736 // then out bind only param
739 __DCL_ASSERT(__buffer == NULL);
740 }
741
742 // __DCL_TRACE3_N("%s, %d, %p\n", Param::__name.data(),
743 // OciData::__valueSize, OciData::__value);
744 status = ::OCIBindByPos(
745 pStmt, // OCIStmt *stmtp,
746 &__bind, // OCIBind **bindp,
747 pError, // OCIError *errhp,
748 OciData::__position, // ub4 position,
749 NULL, // dvoid *valuep,
750 OciData::__valueSize, // sb4 value_sz,
751 OciData::__dataType, // ub2 dty,
752 &__inputIndicator, // dvoid *indp,
753 NULL, // ub2 *alenp,
754 &(OciData::__returnCode), // ub2 *rcodep,
755 0, // ub4 maxarr_len,
756 NULL, // ub4 *curelep,
757 OciData::__dynamicMode // ub4 mode
758 );
759 if (status != OCI_SUCCESS) {
760 __SET_ERROR(SQL::eServerError, status, pError);
761 conn()->setErrorEx(ByteString::format("position[%d]", OciData::__position));
762 return false;
763 }
764 __DCL_ASSERT(__bind != NULL); // bindDynamic은 bindByPos 이후에
765 if (OciData::__dynamicMode == OCI_DATA_AT_EXEC) {
766 status = ::OCIBindDynamic(
767 __bind, // OCIBind *bindp,
768 pError, // OCIError *errhp,
769 this, // dvoid *ictxp,
771 this, // dvoid *octxp
773 );
774 if (status != OCI_SUCCESS) {
775 __SET_ERROR(SQL::eServerError, status, pError);
776 conn()->setErrorEx(ByteString::format("position[%d]", OciData::__position));
777 return false;
778 }
779 }
780
781 return true;
782}
783
785 dvoid *ictxp,
786 OCIBind *bindp,
787 ub4 iter,
788 ub4 index,
789 dvoid **bufpp,
790 ub4 *alenp,
791 ub1 *piecep,
792 dvoid **indpp
793 )
794{
795 return ((OciParam*)ictxp)->onCallbackInBind(
796 bindp,
797 iter,
798 index,
799 bufpp,
800 alenp,
801 piecep,
802 indpp
803 );
804}
805
807 dvoid *octxp,
808 OCIBind *bindp,
809 ub4 iter,
810 ub4 index,
811 dvoid **bufpp,
812 ub4 **alenpp,
813 ub1 *piecep,
814 dvoid **indpp,
815 ub2 **rcodepp
816 )
817{
818 return ((OciParam*)octxp)->onCallbackOutBind(
819 bindp,
820 iter,
821 index,
822 bufpp,
823 alenpp,
824 piecep,
825 indpp,
826 rcodepp
827 );
828}
829
830inline size_t __MIN(size_t x, size_t y)
831{
832 return x < y ? x : y;
833}
834
836 OCIBind* pBind,
837 ub4 nIterator,
838 ub4 _index,
839 dvoid** ppvBuffer,
840 ub4* pnActualLength,
841 ub1* pnPiece,
842 dvoid** ppvIndicator
843 )
844{
845
846//#ifdef __DCL_DEBUG
847// switch(*pnPiece)
848// {
849// case OCI_ONE_PIECE :
850// __DCL_TRACE1_N(L"OCI_ONE_PIECE: %s\n", UTF8Decoder::decode(Param::__name).data());
851// break;
852// case OCI_FIRST_PIECE :
853// __DCL_TRACE1_N(L"OCI_FIRST_PIECE: %s\n", UTF8Decoder::decode(Param::__name).data());
854// break;
855// case OCI_NEXT_PIECE :
856// __DCL_TRACE1_N(L"OCI_NEXT_PIECE: %s\n", UTF8Decoder::decode(Param::__name).data());
857// break;
858// case OCI_LAST_PIECE :
859// __DCL_TRACE1_N(L"OCI_LAST_PIECE: %s\n", UTF8Decoder::decode(Param::__name).data());
860// }
861//#endif
862
863 if (__inputIndicator == -1) {
864 *ppvBuffer = NULL;
865 *pnActualLength = 0;
866 *pnPiece = OCI_ONE_PIECE;
867 *ppvIndicator = &__inputIndicator;
868 return OCI_CONTINUE;
869 }
870
871 if (__inputStream) {
873 || OciData::__dataType == SQLT_BIN
874 || OciData::__dataType == SQLT_LNG
875 || OciData::__dataType == SQLT_LBI);
876
877 if (!__buffer) {
878 __buffer = malloc(DYNAMIC_BUFFER_SIZE);
879 if (!__buffer) {
881 return OCI_ERROR;
882 }
883 }
884
885 __DCL_ASSERT(__buffer != NULL);
886
887 size_t nRead = __MIN((size_t)OciData::__valueSize, DYNAMIC_BUFFER_SIZE);
888
889 if (nRead) {
890 try {
891 nRead = __inputStream->read(__buffer, nRead);
892 }
893 catch(IOException* e) {
894 conn()->setErrorEx(UTF8Encoder::encode(e->toStringAll()));
895 e->destroy();
896 return OCI_ERROR;
897 }
898 }
899
900 if (*pnPiece == OCI_FIRST_PIECE) {
901 if (nRead == (size_t)OciData::__valueSize)
902 *pnPiece = OCI_ONE_PIECE;
903 }
904 else {
905 // OCI_NEXT_PIECE
906 if (nRead == 0 || nRead == (size_t)OciData::__valueSize)
907 *pnPiece = OCI_LAST_PIECE;
908 }
909
910 OciData::__valueSize -= nRead;
911
912 *ppvBuffer = __buffer;
913 *pnActualLength = nRead;
914 *ppvIndicator = NULL;
915 }
916 else {
918 // 입력이 TIMESTAMP와 같은 디스크립터일 경우 버퍼에 이들의 값을
919 // 넣어 준다.
920 *ppvBuffer = __data.desc;
921 }
922 else {
923 // 나머지 경우 OciData::m_pValue는
924 // 외부에서 받은 char*, byte_t* 그리고 &OciParam::__data 이다.
925 *ppvBuffer = OciData::__value;
926 }
927 *pnActualLength = OciData::__valueSize;
928 *pnPiece = OCI_ONE_PIECE;
929 *ppvIndicator = &__inputIndicator;
930 }
931
932 return OCI_CONTINUE;
933}
934
936 OCIBind* pBind,
937 ub4 nIterator,
938 ub4 _index,
939 dvoid** ppvBuffer,
940 ub4** ppnActualLength,
941 ub1* pnPiece,
942 dvoid** ppvIndicator,
943 ub2** ppnReturnCode
944 )
945{
946 __DCL_ASSERT(OciData::__dynamicMode == OCI_DATA_AT_EXEC);
947 /*
948 if (_index == 0) {
949 ub4 nRows = 0;
950 ub4 _size = 0;
951
952 sword status = ::OCIAttrGet(
953 __bind,
954 OCI_HTYPE_BIND,
955 &nRows,
956 &_size,
957 OCI_ATTR_ROWS_RETURNED,
958 query()->connection()->errorHandle());
959 if (status != OCI_SUCCESS) {
960 return OCI_ERROR;
961 }
962 }
963 */
964/*
965#ifdef __DCL_DEBUG
966 switch(*pnPiece) {
967 case OCI_ONE_PIECE :
968 __DCL_TRACE1_N("OCI_ONE_PIECE: %s\n", Param::__name.data());
969 break;
970 case OCI_FIRST_PIECE :
971 __DCL_TRACE1_N("OCI_FIRST_PIECE: %s\n", Param::__name.data());
972 break;
973 case OCI_NEXT_PIECE :
974 __DCL_TRACE1_N("OCI_NEXT_PIECE: %s\n", Param::__name.data());
975 break;
976 case OCI_LAST_PIECE :
977 __DCL_TRACE1_N("OCI_LAST_PIECE: %s\n", Param::__name.data());
978 }
979#endif
980*/
981 if (OciData::__dataType == SQLT_CHR
982 || OciData::__dataType == SQLT_BIN
983 || OciData::__dataType == SQLT_LNG
984 || OciData::__dataType == SQLT_LBI) {
985 if (*pnPiece == OCI_ONE_PIECE)
986 *pnPiece = OCI_FIRST_PIECE;
987
988 if (*pnPiece == OCI_FIRST_PIECE) {
989 if (!__buffer) {
990 __buffer = malloc(DYNAMIC_BUFFER_SIZE);
991 if (!__buffer) {
993 return OCI_ERROR;
994 }
995 }
996
997 OciData::__value = __buffer;
999 __bytesOutput->reset();
1000 }
1001 else {
1002 // 두번째 PIECE 부터는 이전 데이터를 내부 스트림에 보관한다.
1007 return OCI_ERROR;
1008 }
1009 }
1010
1012 try {
1016 );
1017 }
1018 catch(IOException* e) {
1019 conn()->setErrorEx(
1020 UTF8Encoder::encode(e->toStringAll())
1021 );
1022 e->destroy();
1023 return OCI_ERROR;
1024 }
1025 }
1026
1029
1030 *ppvBuffer = OciData::__value;
1031 *ppnActualLength = &(OciData::__callbackActualLength);
1032 *ppvIndicator = &(OciData::__indicator);
1033 *ppnReturnCode = &(OciData::__returnCode);
1034 }
1035 else {
1036 // 버퍼가 OCIDateTime*, OCILogLocator*, OCIRowid* 와 같은
1037 // void*의 디스크립터 일 경우 ppvBuffer에는 이들 디스크립터의
1038 // 값을 넣어 주어야 한다.
1039 // 그러나, OciData::getData에서는 OciData::m_pValue를 사용하여
1040 // 값을 얻기 때문에 이들의 주소를 할당해야 한다.
1041 // OCIDateTime의 경우 *(OCIDateTime**)OciData::__value 와 같이 사용된다.
1042 //
1043 // OCINumber, OCIDate와 같은 경우 이들의 포인터를 할당한다.
1044 if (OciData::__descType) {
1045 OciData::__value = &__data.desc;
1046 OciData::__callbackActualLength = sizeof(void*);
1047 *ppvBuffer = __data.desc;
1048 }
1049 else {
1050 OciData::__value = &__data;
1052 *ppvBuffer = &__data;
1053 }
1055
1056 *pnPiece = OCI_ONE_PIECE;
1057 *ppnActualLength = &(OciData::__callbackActualLength);//NULL;
1058 *ppvIndicator = &(OciData::__indicator);
1059 *ppnReturnCode = &(OciData::__returnCode);
1060 }
1061
1062 return OCI_CONTINUE;
1063}
1064
1065__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 __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:830
#define __SET_ERROR(_errorCode)
Definition SQLCore.cpp:150
void CharsetConvertException *size_t n
Definition SQLField.cpp:253
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:844
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:62
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:264
bool setTimeStamp(const SQL::TimeStamp *_pv, size_t _size, SQL::DataType _assignType)
Definition OciParam.cpp:555
sb4 onCallbackInBind(OCIBind *pBind, ub4 nIterator, ub4 _index, dvoid **ppvBuffer, ub4 *pnActualLength, ub1 *pnPiece, dvoid **ppvIndicator)
Definition OciParam.cpp:835
virtual bool isNull() const
Definition OciParam.cpp:254
static sb4 CallbackInBind(dvoid *ictxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp)
Definition OciParam.cpp:784
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:935
virtual bool __getData(void *_pv, size_t *_size, SQL::DataType _dataType)
Definition OciParam.cpp:272
virtual void setNull()
Definition OciParam.cpp:281
virtual bool __setData(_CONST void *_pv, size_t _size, SQL::DataType _dataType, SQL::DataType _assignType)
Definition OciParam.cpp:292
OciQuery * query() const
Definition OciParam.h:27
bool setInterval(const SQL::Interval *_pv, size_t _size, SQL::DataType _assignType)
Definition OciParam.cpp:630
virtual const wchar_t * serverDataTypeName() const
Definition OciParam.cpp:259
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:806
virtual ~OciParam()
Definition OciParam.cpp:61
bool doBind()
Definition OciParam.cpp:728
ub2 _dataType() const
Definition OciParam.h:29
DataType
Definition SQLCore.h:62
@ typeBinary
Definition SQLCore.h:76
@ typeClob
Definition SQLCore.h:79
@ typeNumeric
Definition SQLCore.h:67
@ typeTime
Definition SQLCore.h:69
@ typeLongBinary
Definition SQLCore.h:78
@ typeUInteger
Definition SQLCore.h:65
@ typeUnknown
Definition SQLCore.h:63
@ typeTimeStamp
Definition SQLCore.h:70
@ typeBlob
Definition SQLCore.h:80
@ typeInputStream
Definition SQLCore.h:83
@ typeTimeStampTz
Definition SQLCore.h:71
@ typeInterval
Definition SQLCore.h:72
@ typeIntervalDs
Definition SQLCore.h:74
@ typeDate
Definition SQLCore.h:68
@ typeText
Definition SQLCore.h:75
@ typeFloat
Definition SQLCore.h:66
@ typeInteger
Definition SQLCore.h:64
@ typeIntervalYm
Definition SQLCore.h:73
@ typeLongText
Definition SQLCore.h:77
@ 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
uint8_t nMonth
Definition SQLCore.h:97
int16_t nYear
Definition SQLCore.h:96
uint8_t nDay
Definition SQLCore.h:98
int8_t nHours
Definition SQLCore.h:128
int32_t nFracs
Definition SQLCore.h:131
int8_t nSecs
Definition SQLCore.h:130
int8_t nMins
Definition SQLCore.h:129
int32_t nYears
Definition SQLCore.h:125
int8_t nMonths
Definition SQLCore.h:126
int32_t nDays
Definition SQLCore.h:127
int16_t nYear
Definition SQLCore.h:111
uint8_t nDay
Definition SQLCore.h:113
uint8_t nHour
Definition SQLCore.h:114
int16_t nTzMin
Definition SQLCore.h:118
uint8_t nSec
Definition SQLCore.h:116
uint8_t nMonth
Definition SQLCore.h:112
uint8_t nMin
Definition SQLCore.h:115
uint32_t nFrac
Definition SQLCore.h:117