Logo ROOT  
Reference Guide
TOracleStatement.cxx
Go to the documentation of this file.
1// @(#)root/oracle:$Id$
2// Author: Sergey Linev 6/02/2006
3
4
5/*************************************************************************
6 * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13//////////////////////////////////////////////////////////////////////////
14// //
15// SQL statement class for Oracle //
16// //
17// See TSQLStatement class documentation for more details. //
18// //
19//////////////////////////////////////////////////////////////////////////
20
21#include "TOracleStatement.h"
22#include "TOracleServer.h"
23#include "TDataType.h"
24#include <stdlib.h>
25
27
28using namespace std;
29using namespace oracle::occi;
30
31
32////////////////////////////////////////////////////////////////////////////////
33/// Normal constructor of TOracleStatement class
34/// On creation time specifies buffer length, which should be
35/// used in data fetching or data inserting
36
37TOracleStatement::TOracleStatement(Environment* env, Connection* conn, Statement* stmt, Int_t niter, Bool_t errout) :
38 TSQLStatement(errout),
39 fEnv(env),
40 fConn(conn),
41 fStmt(stmt),
42 fNumIterations(niter),
43 fTimeFmt(TOracleServer::GetDatimeFormat())
44{
45 if (fStmt) {
46 fStmt->setPrefetchMemorySize(1000000);
47 fStmt->setPrefetchRowCount(niter);
48 fStmt->setMaxIterations(niter);
49 }
50}
51
52////////////////////////////////////////////////////////////////////////////////
53/// Destructor of TOracleStatement clas
54
56{
57 Close();
58}
59
60////////////////////////////////////////////////////////////////////////////////
61/// Close Oracle statement
62/// Removes and destroys all buffers and metainfo
63
65{
66
67 if (fFieldInfo)
68 delete fFieldInfo;
69
70 if (fResult && fStmt)
71 fStmt->closeResultSet(fResult);
72
73 if (fConn && fStmt)
74 fConn->terminateStatement(fStmt);
75
77
78 fConn = nullptr;
79 fStmt = nullptr;
80 fResult = nullptr;
81 fFieldInfo = nullptr;
82 fIterCounter = 0;
83}
84
85// Check that statement is ready for use
86#define CheckStatement(method, res) \
87 { \
88 ClearError(); \
89 if (fStmt==0) { \
90 SetError(-1,"Statement is not correctly initialized",method); \
91 return res; \
92 } \
93 }
94
95// Check that parameter can be set for statement
96#define CheckSetPar(method) \
97 { \
98 CheckStatement(method, kFALSE); \
99 if (!IsParSettMode()) { \
100 SetError(-1,"Parameters cannot be set for this statement", method); \
101 return kFALSE; \
102 } \
103 if (npar<0) { \
104 TString errmsg("Invalid parameter number "); \
105 errmsg+= npar; \
106 SetError(-1,errmsg.Data(),method); \
107 return kFALSE; \
108 } \
109 }
110
111#define CheckGetField(method, defres) \
112 { \
113 ClearError(); \
114 if (!IsResultSet()) { \
115 SetError(-1,"There is no result set for statement", method); \
116 return defres; \
117 } \
118 if ((npar<0) || (npar>=fBufferSize)) { \
119 TString errmsg("Invalid parameter number "); \
120 errmsg+= npar; \
121 SetError(-1,errmsg.Data(),method); \
122 return defres; \
123 } \
124 }
125
126////////////////////////////////////////////////////////////////////////////////
127/// Set buffer size, which is used to keep string values of
128/// currently fetched column.
129
131{
132 CloseBuffer();
133 if (size<=0) return;
134 fBufferSize = size;
135 fBuffer = new TBufferRec[size];
136 for (Int_t n=0;n<fBufferSize;n++) {
137 fBuffer[n].membuf = nullptr;
138 fBuffer[n].bufsize = -1;
139 }
140}
141
142////////////////////////////////////////////////////////////////////////////////
143/// Destroy buffers, used in data fetching
144
146{
147 if (fBuffer) {
148 for (Int_t n=0;n<fBufferSize;n++) {
149 if (fBuffer[n].membuf)
150 free(fBuffer[n].membuf);
151 }
152
153 delete[] fBuffer;
154 }
155 fBuffer = nullptr;
156 fBufferSize = 0;
157}
158
159////////////////////////////////////////////////////////////////////////////////
160/// Process SQL statement
161
163{
164 CheckStatement("Process", kFALSE);
165
166 try {
167
168 if (IsParSettMode()) {
169 fStmt->executeUpdate();
170 fWorkingMode = 0;
171 } else {
172 fStmt->execute();
173 }
174
175 return kTRUE;
176 } catch (SQLException &oraex) {
177 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "Process");
178 }
179
180 return kFALSE;
181}
182
183////////////////////////////////////////////////////////////////////////////////
184/// Return number of affected rows after statement Process() was called
185/// Make sense for queries like SELECT, INSERT, UPDATE
186
188{
189 CheckStatement("GetNumAffectedRows", -1);
190
191 try {
192 return fStmt->getUpdateCount();
193 } catch (SQLException &oraex) {
194 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetNumAffectedRows");
195 }
196 return -1;
197}
198
199
200////////////////////////////////////////////////////////////////////////////////
201/// Return number of parameters in statement
202/// Not yet implemented for Oracle
203
205{
206 CheckStatement("GetNumParameters", -1);
207
208 Info("GetParametersNumber","Not implemented");
209
210 return 0;
211}
212
213////////////////////////////////////////////////////////////////////////////////
214/// Set NULL as value of parameter npar
215
217{
218 CheckSetPar("SetNull");
219
220 try {
221 fStmt->setNull(npar+1, OCCIINT);
222
223 return kTRUE;
224 } catch (SQLException &oraex) {
225 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetNull");
226 }
227
228 return kFALSE;
229}
230
231
232////////////////////////////////////////////////////////////////////////////////
233/// Set integer value for parameter npar
234
236{
237 CheckSetPar("SetInt");
238
239 try {
240 fStmt->setInt(npar+1, value);
241
242 return kTRUE;
243 } catch (SQLException &oraex) {
244 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetInt");
245 }
246
247 return kFALSE;
248}
249
250////////////////////////////////////////////////////////////////////////////////
251/// Set unsigned integer value for parameter npar
252
254{
255 CheckSetPar("SetUInt");
256
257 try {
258 fStmt->setUInt(npar+1, value);
259 return kTRUE;
260 } catch (SQLException &oraex) {
261 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetUInt");
262 }
263
264 return kFALSE;
265}
266
267////////////////////////////////////////////////////////////////////////////////
268/// Set long integer value for parameter npar
269
271{
272 CheckSetPar("SetLong");
273
274 try {
275 fStmt->setNumber(npar+1, Number(value));
276 return kTRUE;
277 } catch (SQLException &oraex) {
278 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetLong");
279 }
280 return kFALSE;
281}
282
283////////////////////////////////////////////////////////////////////////////////
284/// Set 64-bit integer value for parameter npar
285
287{
288 CheckSetPar("SetLong64");
289
290 try {
291 fStmt->setNumber(npar+1, Number((long double)value));
292 return kTRUE;
293 } catch (SQLException &oraex) {
294 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetLong64");
295 }
296 return kFALSE;
297}
298
299////////////////////////////////////////////////////////////////////////////////
300/// Set unsigned 64-bit integer value for parameter npar
301
303{
304 CheckSetPar("SetULong64");
305
306 try {
307 fStmt->setNumber(npar+1, Number((long double)value));
308 return kTRUE;
309 } catch (SQLException &oraex) {
310 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetULong64");
311 }
312 return kFALSE;
313}
314
315////////////////////////////////////////////////////////////////////////////////
316/// Set double value for parameter npar
317
319{
320 CheckSetPar("SetDouble");
321
322 try {
323 fStmt->setDouble(npar+1, value);
324 return kTRUE;
325 } catch (SQLException &oraex) {
326 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetDouble");
327 }
328 return kFALSE;
329}
330
331////////////////////////////////////////////////////////////////////////////////
332/// Set string value for parameter npar
333
334Bool_t TOracleStatement::SetString(Int_t npar, const char* value, Int_t maxsize)
335{
336 CheckSetPar("SetString");
337
338 try {
339
340 // this is when NextIteration is called first time
341 if (fIterCounter==1) {
342 fStmt->setDatabaseNCHARParam(npar+1, true);
343 fStmt->setMaxParamSize(npar+1, maxsize);
344 }
345
346 fStmt->setString(npar+1, value);
347 return kTRUE;
348 } catch (SQLException &oraex) {
349 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetString");
350 }
351 return kFALSE;
352}
353
354////////////////////////////////////////////////////////////////////////////////
355/// set parameter value as binary data
356
357Bool_t TOracleStatement::SetBinary(Int_t npar, void* mem, Long_t size, Long_t maxsize)
358{
359 CheckSetPar("SetBinary");
360
361 try {
362
363 // this is when NextIteration is called first time
364 if (fIterCounter==1)
365 fStmt->setMaxParamSize(npar+1, maxsize);
366
367 Bytes buf((unsigned char*) mem, size);
368
369 fStmt->setBytes(npar+1, buf);
370
371 return kTRUE;
372
373 } catch (SQLException &oraex) {
374 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetBinary");
375 }
376 return kFALSE;
377}
378
379////////////////////////////////////////////////////////////////////////////////
380/// Set date value for parameter npar
381
383{
384 CheckSetPar("SetDate");
385
386 try {
387 Date tm = fStmt->getDate(npar+1);
388 int o_year;
389 unsigned int o_month, o_day, o_hour, o_minute, o_second;
390 tm.getDate(o_year, o_month, o_day, o_hour, o_minute, o_second);
391 tm.setDate(year, month, day, o_hour, o_minute, o_second);
392 fStmt->setDate(npar+1, tm);
393 return kTRUE;
394 } catch (SQLException &oraex) {
395 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetDate");
396 }
397
398 return kFALSE;
399}
400
401////////////////////////////////////////////////////////////////////////////////
402/// Set time value for parameter npar
403
405{
406 CheckSetPar("SetTime");
407
408 try {
409 Date tm = fStmt->getDate(npar+1);
410 int o_year;
411 unsigned int o_month, o_day, o_hour, o_minute, o_second;
412 tm.getDate(o_year, o_month, o_day, o_hour, o_minute, o_second);
413 tm.setDate(o_year, o_month, o_day, hour, min, sec);
414 fStmt->setDate(npar+1, tm);
415 return kTRUE;
416 } catch (SQLException &oraex) {
417 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetTime");
418 }
419
420 return kFALSE;
421}
422
423////////////////////////////////////////////////////////////////////////////////
424/// Set date & time value for parameter npar
425
426Bool_t TOracleStatement::SetDatime(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec)
427{
428 CheckSetPar("SetDatime");
429
430 try {
431 Date tm(fEnv, year, month, day, hour, min, sec);
432 fStmt->setDate(npar+1, tm);
433 return kTRUE;
434 } catch (SQLException &oraex) {
435 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetDatime");
436 }
437
438 return kFALSE;
439}
440
441////////////////////////////////////////////////////////////////////////////////
442/// Set date & time value for parameter npar
443
444Bool_t TOracleStatement::SetTimestamp(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec, Int_t frac)
445{
446 CheckSetPar("SetTimestamp");
447
448 try {
449 Timestamp tm(fEnv, year, month, day, hour, min, sec, frac);
450 fStmt->setTimestamp(npar+1, tm);
451 return kTRUE;
452 } catch (SQLException &oraex) {
453 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetTimestamp");
454 }
455
456 return kFALSE;
457}
458
459////////////////////////////////////////////////////////////////////////////////
460/// Set vector of integer values for parameter npar
461
462Bool_t TOracleStatement::SetVInt(Int_t npar, const std::vector<Int_t> value, const char* schemaName, const char* typeName)
463{
464 CheckSetPar("SetVInt");
465
466 try {
467 setVector(fStmt, npar+1, value, schemaName, typeName);
468 return kTRUE;
469 } catch (SQLException &oraex) {
470 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetVInt");
471 }
472
473 return kFALSE;
474}
475
476////////////////////////////////////////////////////////////////////////////////
477/// Set vector of unsigned integer values for parameter npar
478
479Bool_t TOracleStatement::SetVUInt(Int_t npar, const std::vector<UInt_t> value, const char* schemaName, const char* typeName)
480{
481 CheckSetPar("SetVUInt");
482
483 try {
484 setVector(fStmt, npar+1, value, schemaName, typeName);
485 return kTRUE;
486 } catch (SQLException &oraex) {
487 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetVUInt");
488 }
489
490 return kFALSE;
491}
492
493////////////////////////////////////////////////////////////////////////////////
494/// Set vector of long integer values for parameter npar
495
496Bool_t TOracleStatement::SetVLong(Int_t npar, const std::vector<Long_t> value, const char* schemaName, const char* typeName)
497{
498 CheckSetPar("SetVLong");
499
500 try {
501 std::vector<Number> nvec;
502 for (std::vector<Long_t>::const_iterator it = value.begin();
503 it != value.end();
504 ++it) {
505 nvec.push_back(Number(*it));
506 }
507 setVector(fStmt, npar+1, nvec, schemaName, typeName);
508 return kTRUE;
509 } catch (SQLException &oraex) {
510 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetVLong");
511 }
512 return kFALSE;
513}
514
515////////////////////////////////////////////////////////////////////////////////
516/// Set vector of 64-bit integer values for parameter npar
517
518Bool_t TOracleStatement::SetVLong64(Int_t npar, const std::vector<Long64_t> value, const char* schemaName, const char* typeName)
519{
520 CheckSetPar("SetVLong64");
521
522 try {
523 std::vector<Number> nvec;
524 for (std::vector<Long64_t>::const_iterator it = value.begin();
525 it != value.end();
526 ++it) {
527 nvec.push_back(Number((long double)*it));
528 }
529 setVector(fStmt, npar+1, nvec, schemaName, typeName);
530 return kTRUE;
531 } catch (SQLException &oraex) {
532 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetVLong64");
533 }
534 return kFALSE;
535}
536
537////////////////////////////////////////////////////////////////////////////////
538/// Set vector of unsigned 64-bit integer values for parameter npar
539
540Bool_t TOracleStatement::SetVULong64(Int_t npar, std::vector<ULong64_t> value, const char* schemaName, const char* typeName)
541{
542 CheckSetPar("SetVULong64");
543
544 try {
545 std::vector<Number> nvec;
546 for (std::vector<ULong64_t>::const_iterator it = value.begin();
547 it != value.end();
548 ++it) {
549 nvec.push_back(Number((long double)*it));
550 }
551 setVector(fStmt, npar+1, nvec, schemaName, typeName);
552 return kTRUE;
553 } catch (SQLException &oraex) {
554 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetVULong64");
555 }
556 return kFALSE;
557}
558
559////////////////////////////////////////////////////////////////////////////////
560/// Set vector of double values for parameter npar
561
562Bool_t TOracleStatement::SetVDouble(Int_t npar, const std::vector<Double_t> value, const char* schemaName, const char* typeName)
563{
564 CheckSetPar("SetVDouble");
565
566 try {
567 setVector(fStmt, npar+1, value, schemaName, typeName);
568 return kTRUE;
569 } catch (SQLException &oraex) {
570 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetVDouble");
571 }
572 return kFALSE;
573}
574
575////////////////////////////////////////////////////////////////////////////////
576/// Add next iteration for statement with parameters
577
579{
580 CheckStatement("NextIteration", kFALSE);
581
582 try {
583 fWorkingMode=1;
584 // if number of iterations achievs limit, execute it and continue to fill
585 if ((fIterCounter % fNumIterations == 0) && (fIterCounter>0)) {
586 fStmt->executeUpdate();
587 }
588
589 if (fIterCounter % fNumIterations != 0) {
590 fStmt->addIteration();
591 }
592
593 fIterCounter++;
594
595 return kTRUE;
596 } catch (SQLException &oraex) {
597 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "NextIteration");
598 }
599 return kFALSE;
600}
601
602////////////////////////////////////////////////////////////////////////////////
603/// Store result of statement processing.
604/// Required to access results of SELECT queries
605
607{
608 CheckStatement("StoreResult", kFALSE);
609
610 try {
611 if (fStmt->status() == Statement::RESULT_SET_AVAILABLE) {
612 fResult = fStmt->getResultSet();
613 fFieldInfo = (fResult==0) ? 0 : new std::vector<MetaData>(fResult->getColumnListMetaData());
614 Int_t count = (fFieldInfo==0) ? 0 : fFieldInfo->size();
615 SetBufferSize(count);
616 if ((fResult!=0) && (count>0)) fWorkingMode = 2;
617
618 return IsResultSet();
619 }
620 } catch (SQLException &oraex) {
621 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "StoreResult");
622 }
623 return kFALSE;
624}
625
626////////////////////////////////////////////////////////////////////////////////
627/// Defines maximum size for field which must be used for read or write operation
628/// Some Oracle types as LONG (long binary continer) requires this call
629/// before any data can be read from database. Call it once before first call to NextResultRow()
630
632{
633 CheckStatement("SetMaxFieldSize", kFALSE);
634
635 try {
636 if (fResult)
637 fResult->setMaxColumnSize(nfield+1, maxsize);
638 else
639 fStmt->setMaxParamSize(nfield+1, maxsize);
640 return kTRUE;
641 } catch (SQLException &oraex) {
642 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetMaxFieldSize");
643 }
644
645 return kFALSE;
646}
647
648////////////////////////////////////////////////////////////////////////////////
649/// Returns number of fields in result set
650
652{
653 return IsResultSet() ? fBufferSize : -1;
654}
655
656////////////////////////////////////////////////////////////////////////////////
657/// Return field name in result set
658
660{
661 CheckGetField("GetFieldName", 0);
662
663 if (!IsResultSet() || (npar<0) || (npar>=fBufferSize)) return nullptr;
664
665 if (fBuffer[npar].namebuf.empty())
666 fBuffer[npar].namebuf = (*fFieldInfo)[npar].getString(MetaData::ATTR_NAME);
667
668 return fBuffer[npar].namebuf.empty() ? nullptr : fBuffer[npar].namebuf.c_str();
669}
670
671////////////////////////////////////////////////////////////////////////////////
672/// Move cursor to next row in result set.
673/// For Oracle it may lead to additional request to database
674
676{
677 ClearError();
678
679 if (fResult==0) {
680 SetError(-1,"There is no result set for statement", "NextResultRow");
681 return kFALSE;
682 }
683
684 if (fResult==0) return kFALSE;
685
686 try {
687 for (int n=0;n<fBufferSize;n++) {
688 if (fBuffer[n].membuf) {
689 free(fBuffer[n].membuf);
690 fBuffer[n].membuf = nullptr;
691 }
692 fBuffer[n].bufsize = -1;
693 }
694 if (fResult->next() == oracle::occi::ResultSet::END_OF_FETCH) {
695 fWorkingMode = 0;
696 CloseBuffer();
697 return kFALSE;
698 }
699 return kTRUE;
700 } catch (SQLException &oraex) {
701 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "NextResultRow");
702
703 if (oraex.getErrorCode()==32108)
704 Info("NextResultRow", "Use TSQLStatement::SetMaxFieldSize() to solve a problem");
705
706 }
707
708 return kFALSE;
709}
710
711////////////////////////////////////////////////////////////////////////////////
712/// Checks if fieled value in result set is NULL
713
715{
716 CheckGetField("IsNull", kFALSE);
717
718 try {
719 return fResult->isNull(npar+1);
720 } catch (SQLException &oraex) {
721 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "IsNull");
722 }
723
724 return kTRUE;
725}
726
727////////////////////////////////////////////////////////////////////////////////
728/// return field value as integer
729
731{
732 CheckGetField("GetInt", 0);
733
734 Int_t res = 0;
735
736 try {
737 if (!fResult->isNull(npar+1))
738 res = fResult->getInt(npar+1);
739 } catch (SQLException &oraex) {
740 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetInt");
741 }
742
743 return res;
744}
745
746////////////////////////////////////////////////////////////////////////////////
747/// return field value as unsigned integer
748
750{
751 CheckGetField("GetUInt", 0);
752
753 UInt_t res = 0;
754
755 try {
756 if (!fResult->isNull(npar+1))
757 res = fResult->getUInt(npar+1);
758 } catch (SQLException &oraex) {
759 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetUInt");
760 }
761
762 return res;
763}
764
765
766////////////////////////////////////////////////////////////////////////////////
767/// return field value as long integer
768
770{
771 CheckGetField("GetLong", 0);
772
773 Long_t res = 0;
774
775 try {
776 if (!fResult->isNull(npar+1))
777 res = (Long_t) fResult->getNumber(npar+1);
778 } catch (SQLException &oraex) {
779 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetLong");
780 }
781
782 return res;
783}
784
785////////////////////////////////////////////////////////////////////////////////
786/// return field value as 64-bit integer
787
789{
790 CheckGetField("GetLong64", 0);
791
792 Long64_t res = 0;
793
794 try {
795 if (!fResult->isNull(npar+1))
796 res = (Long64_t) (long double) fResult->getNumber(npar+1);
797 } catch (SQLException &oraex) {
798 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetLong64");
799 }
800
801 return res;
802}
803
804////////////////////////////////////////////////////////////////////////////////
805/// return field value as unsigned 64-bit integer
806
808{
809 CheckGetField("GetULong64", 0);
810
811 ULong64_t res = 0;
812
813 try {
814 if (!fResult->isNull(npar+1))
815 res = (ULong64_t) (long double) fResult->getNumber(npar+1);
816 } catch (SQLException &oraex) {
817 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetULong64");
818 }
819
820 return res;
821}
822
823////////////////////////////////////////////////////////////////////////////////
824/// return field value as double
825
827{
828 CheckGetField("GetDouble", 0.);
829
830 Double_t res = 0;
831
832 try {
833 if (!fResult->isNull(npar+1))
834 res = fResult->getDouble(npar+1);
835 } catch (SQLException &oraex) {
836 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetDouble");
837 }
838
839 return res;
840}
841
842////////////////////////////////////////////////////////////////////////////////
843/// return field value as string
844
846{
847 CheckGetField("GetString", 0);
848
849 if (fBuffer[npar].membuf)
850 return (const char *) fBuffer[npar].membuf;
851
852 try {
853 if (fResult->isNull(npar+1)) return 0;
854
855 int datatype = (*fFieldInfo)[npar].getInt(MetaData::ATTR_DATA_TYPE);
856
857 std::string res;
858
859 switch (datatype) {
860 case SQLT_NUM: { // oracle numeric NUMBER
861 int prec = (*fFieldInfo)[npar].getInt(MetaData::ATTR_PRECISION);
862 int scale = (*fFieldInfo)[npar].getInt(MetaData::ATTR_SCALE);
863
864 if ((scale == 0) || (prec == 0)) {
865 res = fResult->getString(npar+1);
866 } else {
867 double double_val = fResult->getDouble(npar+1);
868 char str_number[50];
869 snprintf(str_number, sizeof(str_number), TSQLServer::GetFloatFormat(), double_val);
870 res = str_number;
871 }
872 break;
873 }
874 case SQLT_CHR: // character string
875 case SQLT_VCS: // variable character string
876 case SQLT_AFC: // ansi fixed char
877 case SQLT_AVC: // ansi var char
878 res = fResult->getString(npar+1);
879 break;
880 case SQLT_DAT: // Oracle native DATE type
881 res = (fResult->getDate(npar+1)).toText(fTimeFmt.Data());
882 break;
883 case SQLT_TIMESTAMP: // TIMESTAMP
884 case SQLT_TIMESTAMP_TZ: // TIMESTAMP WITH TIMEZONE
885 case SQLT_TIMESTAMP_LTZ: // TIMESTAMP WITH LOCAL TIMEZONE
886 res = (fResult->getTimestamp(npar+1)).toText(fTimeFmt.Data(), 0);
887 break;
888 default:
889 res = fResult->getString(npar+1);
890 Info("getString","Type %d may not be supported", datatype);
891 }
892
893 int len = res.length();
894
895 if (len > 0) {
896 fBuffer[npar].membuf = malloc(len+1);
897 fBuffer[npar].bufsize = len+1;
898 strncpy((char *) fBuffer[npar].membuf, res.c_str(), len+1);
899 }
900
901 return (const char *)fBuffer[npar].membuf;
902
903 } catch (SQLException &oraex) {
904 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetString");
905 }
906
907 return 0;
908}
909
910////////////////////////////////////////////////////////////////////////////////
911/// Return field value as binary array
912/// Supports LONG, BLOB, CLOB, BFILE, CFILE types of columns
913/// Reads complete content of the column, therefore not suitable for
914/// big structures
915
917{
918 mem = 0;
919 size = 0;
920
921 CheckGetField("GetBinary", kFALSE);
922
923 if (fBuffer[npar].bufsize >= 0) {
924 mem = fBuffer[npar].membuf;
925 size = fBuffer[npar].bufsize;
926 return kTRUE;
927 }
928
929 try {
930 if (fResult->isNull(npar+1)) return kTRUE;
931
932 int datatype = (*fFieldInfo)[npar].getInt(MetaData::ATTR_DATA_TYPE);
933
934 switch (datatype) {
935 case SQLT_LNG: {
936 Bytes parbytes = fResult->getBytes(npar+1);
937
938 size = parbytes.length();
939
940 fBuffer[npar].bufsize = size;
941
942 if (size > 0) {
943 mem = malloc(size);
944
945 fBuffer[npar].membuf = mem;
946
947 parbytes.getBytes((unsigned char *) mem, size);
948 }
949
950 break;
951 }
952
953 case SQLT_BLOB: {
954 Blob parblob = fResult->getBlob(npar+1);
955
956 size = parblob.length();
957
958 fBuffer[npar].bufsize = size;
959
960 if (size > 0) {
961 mem = malloc(size);
962
963 fBuffer[npar].membuf = mem;
964
965 parblob.read(size, (unsigned char *) mem, size);
966 }
967
968 break;
969 }
970
971 case SQLT_CLOB: {
972 Clob parclob = fResult->getClob(npar+1);
973
974 size = parclob.length();
975
976 fBuffer[npar].bufsize = size;
977
978 if (size > 0) {
979 mem = malloc(size);
980
981 fBuffer[npar].membuf = mem;
982
983 parclob.read(size, (unsigned char *) mem, size);
984 }
985
986 break;
987 }
988
989 case SQLT_BFILEE:
990 case SQLT_CFILEE: {
991
992 Bfile parbfile = fResult->getBfile(npar+1);
993
994 size = parbfile.length();
995
996 fBuffer[npar].bufsize = size;
997
998 if (size>0) {
999 mem = malloc(size);
1000
1001 fBuffer[npar].membuf = mem;
1002
1003 parbfile.read(size, (unsigned char *) mem, size);
1004 }
1005
1006 break;
1007 }
1008
1009 default:
1010 Error("GetBinary", "Oracle data type %d not supported", datatype);
1011 SetError(-1, "Unsupported type for binary convertion", "GetBinary");
1012 return false;
1013 }
1014
1015 return kTRUE;
1016
1017 } catch (SQLException &oraex) {
1018 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetBinary");
1019 }
1020
1021 return kFALSE;
1022}
1023
1024
1025////////////////////////////////////////////////////////////////////////////////
1026/// return field value as date
1027
1029{
1030 Int_t hour, min, sec;
1031
1032 return GetDatime(npar, year, month, day, hour, min, sec);
1033}
1034
1035////////////////////////////////////////////////////////////////////////////////
1036/// return field value as time
1037
1039{
1040 Int_t year, month, day;
1041
1042 return GetDatime(npar, year, month, day, hour, min, sec);
1043}
1044
1045////////////////////////////////////////////////////////////////////////////////
1046/// return field value as date & time
1047
1048Bool_t TOracleStatement::GetDatime(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec)
1049{
1050 CheckGetField("GetDatime", kFALSE);
1051
1052 try {
1053 if (!fResult->isNull(npar+1)) {
1054 int datatype = (*fFieldInfo)[npar].getInt(MetaData::ATTR_DATA_TYPE);
1055
1056 if (datatype!=SQLT_DAT) return kFALSE;
1057
1058 Date tm = fResult->getDate(npar+1);
1059 int o_year;
1060 unsigned int o_month, o_day, o_hour, o_minute, o_second;
1061 tm.getDate(o_year, o_month, o_day, o_hour, o_minute, o_second);
1062 year = (Int_t) o_year;
1063 month = (Int_t) o_month;
1064 day = (Int_t) o_day;
1065 hour = (Int_t) o_hour;
1066 min = (Int_t) o_minute;
1067 sec = (Int_t) o_second;
1068 return kTRUE;
1069 }
1070 } catch (SQLException &oraex) {
1071 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetDatime");
1072 }
1073
1074 return kFALSE;
1075}
1076
1077////////////////////////////////////////////////////////////////////////////////
1078/// return field value as date & time
1079
1080Bool_t TOracleStatement::GetTimestamp(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec, Int_t& frac)
1081{
1082 CheckGetField("GetTimestamp", kFALSE);
1083
1084 try {
1085 if (!fResult->isNull(npar+1)) {
1086 int datatype = (*fFieldInfo)[npar].getInt(MetaData::ATTR_DATA_TYPE);
1087
1088 if ((datatype!=SQLT_TIMESTAMP) &&
1089 (datatype!=SQLT_TIMESTAMP_TZ) &&
1090 (datatype!=SQLT_TIMESTAMP_LTZ)) return kFALSE;
1091
1092 Timestamp tm = fResult->getTimestamp(npar+1);
1093 int o_year;
1094 unsigned int o_month, o_day, o_hour, o_minute, o_second, o_frac;
1095 tm.getDate(o_year, o_month, o_day);
1096 tm.getTime(o_hour, o_minute, o_second, o_frac);
1097 year = (Int_t) o_year;
1098 month = (Int_t) o_month;
1099 day = (Int_t) o_day;
1100 hour = (Int_t) o_hour;
1101 min = (Int_t) o_minute;
1102 sec = (Int_t) o_second;
1103 frac = (Int_t) o_frac;
1104 return kTRUE;
1105 }
1106 } catch (SQLException &oraex) {
1107 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetTimestamp");
1108 }
1109
1110 return kFALSE;
1111}
1112
1113////////////////////////////////////////////////////////////////////////////////
1114/// return field value as vector of integers
1115
1116Bool_t TOracleStatement::GetVInt(Int_t npar, std::vector<Int_t> &value)
1117{
1118 CheckGetField("GetVInt", kFALSE);
1119 try {
1120 if (!fResult->isNull(npar+1))
1121 getVector(fResult, npar+1, value);
1122 return kTRUE;
1123 } catch (SQLException &oraex) {
1124 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetVInt");
1125 }
1126 return kFALSE;
1127}
1128
1129////////////////////////////////////////////////////////////////////////////////
1130/// return field value as vector of unsigned integers
1131
1132Bool_t TOracleStatement::GetVUInt(Int_t npar, std::vector<UInt_t> &value)
1133{
1134 CheckGetField("GetVUInt", kFALSE);
1135 try {
1136 if (!fResult->isNull(npar+1))
1137 getVector(fResult, npar+1, value);
1138 return kTRUE;
1139 } catch (SQLException &oraex) {
1140 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetVUInt");
1141 }
1142 return kFALSE;
1143}
1144
1145
1146////////////////////////////////////////////////////////////////////////////////
1147/// return field value as vector of long integers
1148
1149Bool_t TOracleStatement::GetVLong(Int_t npar, std::vector<Long_t> &value)
1150{
1151 CheckGetField("GetVLong", kFALSE);
1152 try {
1153 std::vector<Number> res;
1154 if (!fResult->isNull(npar+1))
1155 getVector(fResult, npar+1, res);
1156 for (std::vector<Number>::const_iterator it = res.begin();
1157 it != res.end();
1158 ++it ) {
1159 value.push_back((Long_t)*it);
1160 }
1161 return kTRUE;
1162 } catch (SQLException &oraex) {
1163 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetVLong");
1164 }
1165 return kFALSE;
1166}
1167
1168////////////////////////////////////////////////////////////////////////////////
1169/// return field value as vector of 64-bit integers
1170
1171Bool_t TOracleStatement::GetVLong64(Int_t npar, std::vector<Long64_t> &value)
1172{
1173 CheckGetField("GetVLong64", kFALSE);
1174 try {
1175 std::vector<Number> res;
1176 if (!fResult->isNull(npar+1))
1177 getVector(fResult, npar+1, res);
1178 for (std::vector<Number>::const_iterator it = res.begin();
1179 it != res.end();
1180 ++it ) {
1181 value.push_back((Long_t)*it);
1182 }
1183 return kTRUE;
1184 } catch (SQLException &oraex) {
1185 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetVLong64");
1186 }
1187 return kFALSE;
1188}
1189
1190////////////////////////////////////////////////////////////////////////////////
1191/// return field value as vector of unsigned 64-bit integers
1192
1193Bool_t TOracleStatement::GetVULong64(Int_t npar, std::vector<ULong64_t> &value)
1194{
1195 CheckGetField("GetVULong64", kFALSE);
1196 try {
1197 std::vector<Number> res;
1198 if (!fResult->isNull(npar+1))
1199 getVector(fResult, npar+1, res);
1200 for (std::vector<Number>::const_iterator it = res.begin();
1201 it != res.end();
1202 ++it ) {
1203 value.push_back((Long_t)(long double)*it);
1204 }
1205 return kTRUE;
1206 } catch (SQLException &oraex) {
1207 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetVULong64");
1208 }
1209 return kFALSE;
1210}
1211
1212////////////////////////////////////////////////////////////////////////////////
1213/// return field value as vector of doubles
1214
1215Bool_t TOracleStatement::GetVDouble(Int_t npar, std::vector<Double_t> &value)
1216{
1217 CheckGetField("GetVDouble", kFALSE);
1218 try {
1219 if (!fResult->isNull(npar+1))
1220 getVector(fResult, npar+1, value);
1221 return kTRUE;
1222 } catch (SQLException &oraex) {
1223 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetVDouble");
1224 }
1225 return kFALSE;
1226}
1227
int Int_t
Definition: RtypesCore.h:43
const Bool_t kFALSE
Definition: RtypesCore.h:90
long Long_t
Definition: RtypesCore.h:52
bool Bool_t
Definition: RtypesCore.h:61
long long Long64_t
Definition: RtypesCore.h:71
unsigned long long ULong64_t
Definition: RtypesCore.h:72
const Bool_t kTRUE
Definition: RtypesCore.h:89
const char Option_t
Definition: RtypesCore.h:64
#define ClassImp(name)
Definition: Rtypes.h:361
#define CheckStatement(method, res)
#define CheckSetPar(method)
#define CheckGetField(method, defres)
#define free
Definition: civetweb.c:1539
#define snprintf
Definition: civetweb.c:1540
#define malloc
Definition: civetweb.c:1536
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:891
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:865
Bool_t SetVInt(Int_t npar, const std::vector< Int_t > value, const char *schemaName, const char *typeName) final
Set vector of integer values for parameter npar.
oracle::occi::Statement * fStmt
UInt_t GetUInt(Int_t npar) final
return field value as unsigned integer
Double_t GetDouble(Int_t npar) final
return field value as double
void SetBufferSize(Int_t size)
Set buffer size, which is used to keep string values of currently fetched column.
Long64_t GetLong64(Int_t npar) final
return field value as 64-bit integer
const char * GetString(Int_t npar) final
return field value as string
Bool_t SetDouble(Int_t npar, Double_t value) final
Set double value for parameter npar.
ULong64_t GetULong64(Int_t npar) final
return field value as unsigned 64-bit integer
Bool_t SetLong64(Int_t npar, Long64_t value) final
Set 64-bit integer value for parameter npar.
Bool_t SetVLong64(Int_t npar, const std::vector< Long64_t > value, const char *schemaName, const char *typeName) final
Set vector of 64-bit integer values for parameter npar.
Bool_t SetUInt(Int_t npar, UInt_t value) final
Set unsigned integer value for parameter npar.
oracle::occi::Environment * fEnv
Bool_t GetVDouble(Int_t npar, std::vector< Double_t > &value) final
return field value as vector of doubles
Bool_t GetVULong64(Int_t npar, std::vector< ULong64_t > &value) final
return field value as vector of unsigned 64-bit integers
Bool_t NextResultRow() final
Move cursor to next row in result set.
Bool_t SetBinary(Int_t npar, void *mem, Long_t size, Long_t maxsize=0x1000) final
set parameter value as binary data
virtual ~TOracleStatement()
Destructor of TOracleStatement clas.
Int_t GetNumFields() final
Returns number of fields in result set.
Bool_t SetTimestamp(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec, Int_t frac=0) final
Set date & time value for parameter npar.
const char * GetFieldName(Int_t nfield) final
Return field name in result set.
Bool_t SetDate(Int_t npar, Int_t year, Int_t month, Int_t day) final
Set date value for parameter npar.
Bool_t GetTime(Int_t npar, Int_t &hour, Int_t &min, Int_t &sec) final
return field value as time
Bool_t GetVLong(Int_t npar, std::vector< Long_t > &value) final
return field value as vector of long integers
TBufferRec * fBuffer
Bool_t SetString(Int_t npar, const char *value, Int_t maxsize=256) final
Set string value for parameter npar.
Bool_t SetVUInt(Int_t npar, const std::vector< UInt_t > value, const char *schemaName, const char *typeName) final
Set vector of unsigned integer values for parameter npar.
Bool_t SetMaxFieldSize(Int_t nfield, Long_t maxsize) final
Defines maximum size for field which must be used for read or write operation Some Oracle types as LO...
void CloseBuffer()
Destroy buffers, used in data fetching.
Bool_t SetVULong64(Int_t npar, const std::vector< ULong64_t > value, const char *schemaName, const char *typeName) final
Set vector of unsigned 64-bit integer values for parameter npar.
Bool_t GetVUInt(Int_t npar, std::vector< UInt_t > &value) final
return field value as vector of unsigned integers
Bool_t SetULong64(Int_t npar, ULong64_t value) final
Set unsigned 64-bit integer value for parameter npar.
Bool_t SetLong(Int_t npar, Long_t value) final
Set long integer value for parameter npar.
Bool_t SetTime(Int_t npar, Int_t hour, Int_t min, Int_t sec) final
Set time value for parameter npar.
Bool_t NextIteration() final
Add next iteration for statement with parameters.
Int_t GetInt(Int_t npar) final
return field value as integer
Bool_t IsNull(Int_t) final
Checks if fieled value in result set is NULL.
Bool_t IsParSettMode() const
Bool_t GetVInt(Int_t npar, std::vector< Int_t > &value) final
return field value as vector of integers
Bool_t Process() final
Process SQL statement.
Long_t GetLong(Int_t npar) final
return field value as long integer
TOracleStatement(oracle::occi::Environment *env, oracle::occi::Connection *conn, oracle::occi::Statement *stmt, Int_t niter, Bool_t errout=kTRUE)
Bool_t GetTimestamp(Int_t npar, Int_t &year, Int_t &month, Int_t &day, Int_t &hour, Int_t &min, Int_t &sec, Int_t &frac) final
return field value as date & time
Bool_t SetNull(Int_t npar) final
Set NULL as value of parameter npar.
Int_t GetNumParameters() final
Return number of parameters in statement Not yet implemented for Oracle.
Bool_t SetDatime(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec) final
Set date & time value for parameter npar.
Bool_t GetBinary(Int_t npar, void *&mem, Long_t &size) final
Return field value as binary array Supports LONG, BLOB, CLOB, BFILE, CFILE types of columns Reads com...
void Close(Option_t *="") final
Close Oracle statement Removes and destroys all buffers and metainfo.
oracle::occi::Connection * fConn
Bool_t SetVLong(Int_t npar, const std::vector< Long_t > value, const char *schemaName, const char *typeName) final
Set vector of long integer values for parameter npar.
Bool_t SetVDouble(Int_t npar, const std::vector< Double_t > value, const char *schemaName, const char *typeName) final
Set vector of double values for parameter npar.
Bool_t IsResultSet() const
Bool_t GetDatime(Int_t npar, Int_t &year, Int_t &month, Int_t &day, Int_t &hour, Int_t &min, Int_t &sec) final
return field value as date & time
Bool_t StoreResult() final
Store result of statement processing.
Bool_t GetVLong64(Int_t npar, std::vector< Long64_t > &value) final
return field value as vector of 64-bit integers
Bool_t SetInt(Int_t npar, Int_t value) final
Set integer value for parameter npar.
Int_t GetNumAffectedRows() final
Return number of affected rows after statement Process() was called Make sense for queries like SELEC...
Bool_t GetDate(Int_t npar, Int_t &year, Int_t &month, Int_t &day) final
return field value as date
oracle::occi::ResultSet * fResult
std::vector< oracle::occi::MetaData > * fFieldInfo
static const char * GetFloatFormat()
return current printf format for float/double members, default "%e"
Definition: TSQLServer.cxx:269
void SetError(Int_t code, const char *msg, const char *method=nullptr)
set new values for error fields if method specified, displays error message
void ClearError()
reset error fields
const char * Data() const
Definition: TString.h:364
const Int_t n
Definition: legend1.C:16