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