Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:22:05

0001 // $Id: ODBCPreparedStatement.cxx,v 1.4 2014/02/14 16:51:27 jinhuang Exp $
0002 //*-- Author : Valeriy Onuchin 14/02/2000 
0003 //
0004 
0005 /**************************************************************************
0006 
0007    ROOT wrappers of libodbc++ library
0008     
0009    Copyright (C) 1999-2000 Manush Dodunekov <manush@stendahls.net>
0010    
0011    This library is free software; you can redistribute it and/or
0012    modify it under the terms of the GNU Library General Public
0013    License as published by the Free Software Foundation; either
0014    version 2 of the License, or (at your option) any later version.
0015    
0016    This library is distributed in the hope that it will be useful,
0017    but WITHOUT ANY WARRANTY; without even the implied warranty of
0018    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0019    Library General Public License for more details.
0020    
0021    You should have received a copy of the GNU Library General Public License
0022    along with this library; see the file COPYING.  If not, write to
0023    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
0024    Boston, MA 02111-1307, USA.
0025 
0026 **************************************************************************/
0027 
0028 /////////////////////////////////////////////////////////////////////
0029 //
0030 // An object that represents a precompiled SQL statement. 
0031 //
0032 // A SQL statement is pre-compiled and stored in a 
0033 // TSQLPreparedStatement object. This object can then be used to 
0034 // efficiently  ODBCPreparedStatement::Execute() this statement 
0035 // multiple times. 
0036 //
0037 // Note: The ODBCPreparedStatement::SetXXX methods for setting IN 
0038 //    parameter values must specify types that are compatible with the 
0039 //    defined SQL type of the input parameter. For instance, if the 
0040 //    IN parameter has SQL type integer, then the method 
0041 //    ODBCPreparedStatement::SetInt() should be used. 
0042 //
0043 // Example of TSQLPreparedStatement setting a parameter; 
0044 // con is an active connection 
0045 //
0046 //
0047 //  TSQLPreparedStatement* pstmt = 
0048 //       con->PrepareStatement("UPDATE EMPLOYEES SET SALARY = ?  
0049 //                               WHERE ID = ?");
0050 //
0051 //   pstmt->SetInt(2, 110592);
0052 // 
0053 //
0054 // See also: 
0055 //      TSQLConnection::PrepareStatement(const TString&), 
0056 //      TSQLResultSet TSQLStatement TSQLCallableStatement
0057 //
0058 //
0059 /////////////////////////////////////////////////////////////////////
0060 
0061 #include "ODBCPreparedStatement.h"
0062 #include "ODBCResultSet.h"
0063 #include <RDBC/odbc++/statement.h>
0064 #include <RDBC/odbc++/preparedstatement.h>
0065 #include <RDBC/odbc++/resultset.h>
0066 #include <iostream>
0067 #include <sstream>
0068 #include <TList.h>
0069 
0070 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,0)
0071 #include <TBufferFile.h>
0072 #endif
0073 
0074 using namespace std;
0075 using namespace odbc;
0076 
0077 ClassImpQ(ODBCPreparedStatement)
0078 
0079 /////////////////////////////////////////////////////////////////////
0080 //___________________________________________________________________
0081 ODBCPreparedStatement::ODBCPreparedStatement(TSQLConnection* con,void* imp):
0082          TSQLPreparedStatement(con,imp)
0083    
0084 {
0085    // ctor
0086 }
0087 
0088 //___________________________________________________________________
0089 ODBCPreparedStatement::~ODBCPreparedStatement()
0090 {
0091    // dtor
0092 
0093    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0094  
0095    try { 
0096       if(imp) delete  imp;   
0097    } catch(odbc::SQLException& e) {
0098       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0099                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0100                                 e.getErrorCode()) );
0101    }
0102 
0103   // implementation part of fCurrentResult is deleted with statement
0104    if(fCurrentResult) ((ODBCResultSet*)fCurrentResult)->fImp = 0;
0105    fImp = 0;
0106 }
0107 
0108 //___________________________________________________________________
0109 void ODBCPreparedStatement::SetNull( Int_t parameterIndex,Int_t sqlType )
0110 {
0111    // Sets the designated parameter to SQL NULL. 
0112    //
0113    //   Note: You must specify the parameter's SQL type.
0114    //
0115    //   Parameters:
0116    //          parameterIndex - the first parameter is 1, 
0117    //                           the second is 2, ...
0118    //          sqlType - the SQL type code defined in TSQLTypes
0119    //   Throws:
0120    //          TSQLException - if a database access error occurs
0121    
0122    if(!fImp) { Destroyed();   return; } 
0123    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0124      
0125    try {
0126       imp->setNull(parameterIndex,sqlType);
0127 
0128    } catch(odbc::SQLException& e) {
0129       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0130                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0131                                 e.getErrorCode()) );
0132    }
0133 }
0134 
0135 //___________________________________________________________________
0136 void ODBCPreparedStatement::SetBoolean( Int_t parameterIndex,Bool_t x )
0137 {
0138    // Sets the designated parameter to a Bool_t value. The
0139    // driver converts this to an SQL BIT value when it sends it to
0140    // the database.
0141    //
0142    //   Parameters:
0143    //         parameterIndex - the first parameter is 1, 
0144    //                          the second is 2, ...
0145    //         x - the parameter value
0146    //   Throws:
0147    //         TSQLException - if a database access error occurs
0148    
0149    if(!fImp) { Destroyed();   return; } 
0150    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0151    
0152    try {
0153       imp->setBoolean(parameterIndex,x); 
0154 
0155    } catch(odbc::SQLException& e) {
0156       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0157                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0158                                 e.getErrorCode()) );
0159    }
0160 }
0161 
0162 //___________________________________________________________________
0163 void ODBCPreparedStatement::SetByte( Int_t parameterIndex,Char_t x )
0164 {
0165    // Sets the designated parameter to a  byte value. The
0166    // driver converts this to an SQL TINYINT value when it sends
0167    // it to the database.
0168    //
0169    //   Parameters:
0170    //         parameterIndex - the first parameter is 1, 
0171    //                          the second is 2, ...
0172    //         x - the parameter value
0173    //   Throws:
0174    //         TSQLException - if a database access error occurs
0175    
0176    if(!fImp) { Destroyed();   return; } 
0177    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0178    
0179    try {   
0180       imp->setByte(parameterIndex,x); 
0181 
0182    } catch(odbc::SQLException& e) {
0183       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0184                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0185                                 e.getErrorCode()) );
0186    }
0187 }
0188 
0189 //___________________________________________________________________
0190 void ODBCPreparedStatement::SetShort( Int_t parameterIndex,Short_t x )
0191 {
0192    // Sets the designated parameter to a  short value. The
0193    //   driver converts this to an SQL SMALLINT value when it sends
0194    //   it to the database.
0195    //
0196    //   Parameters:
0197    //         parameterIndex - the first parameter is 1, 
0198    //                            the second is 2, ...
0199    //         x - the parameter value
0200    //   Throws:
0201    //         TSQLException - if a database access error occurs
0202 
0203    if(!fImp) { Destroyed();   return; } 
0204    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0205    
0206    try {
0207       imp->setShort(parameterIndex,x);
0208 
0209    } catch(odbc::SQLException& e) {
0210       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0211                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0212                                 e.getErrorCode()) );
0213    }
0214 }
0215 
0216 //___________________________________________________________________
0217 void ODBCPreparedStatement::SetInt( Int_t parameterIndex,Int_t x )
0218 {
0219    // Sets the designated parameter to a  int value. The
0220    // driver converts this to an SQL INTEGER value when it sends
0221    // it to the database.
0222    //
0223    //   Parameters:
0224    //         parameterIndex - the first parameter is 1, 
0225    //                          the second is 2, ...
0226    //         x - the parameter value
0227    //   Throws:
0228    //         TSQLException - if a database access error occurs
0229    
0230    if(!fImp) { Destroyed();   return; } 
0231    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0232    
0233    try {
0234       imp->setInt(parameterIndex,x);
0235 
0236    } catch(odbc::SQLException& e) {
0237       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0238                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0239                                 e.getErrorCode()) );
0240    }
0241 }
0242 
0243 //___________________________________________________________________
0244 void ODBCPreparedStatement::SetLong( Int_t parameterIndex,Long_t x )
0245 {
0246    // Sets the designated parameter to a  long value. The
0247    // driver converts this to an SQL BIGINT value when it sends it
0248    // to the database.
0249    //
0250    //   Parameters:
0251    //         parameterIndex - the first parameter is 1, 
0252    //                          the second is 2, ...
0253    //         x - the parameter value
0254    //   Throws:
0255    //         TSQLException - if a database access error occurs
0256    
0257    if(!fImp) { Destroyed();   return; } 
0258    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0259    
0260    try {
0261       imp->setLong(parameterIndex,x);
0262 
0263    } catch(odbc::SQLException& e) {
0264       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0265                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0266                                 e.getErrorCode()) );
0267    }
0268 }
0269 
0270 //___________________________________________________________________
0271 void ODBCPreparedStatement::SetFloat( Int_t parameterIndex,Float_t x )
0272 {
0273    // Sets the designated parameter to a  float value. The
0274    // driver converts this to an SQL FLOAT value when it sends it
0275    // to the database.
0276    //
0277    //   Parameters:
0278    //         parameterIndex - the first parameter is 1, 
0279    //                          the second is 2, ...
0280    //         x - the parameter value
0281    //   Throws:
0282    //         TSQLException - if a database access error occurs
0283    
0284    if(!fImp) { Destroyed();   return; } 
0285    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0286    
0287    try {
0288       imp->setFloat(parameterIndex,x);
0289 
0290    } catch(odbc::SQLException& e) {
0291       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0292                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0293                                 e.getErrorCode()) );
0294    }
0295 }
0296 
0297 //___________________________________________________________________
0298 void ODBCPreparedStatement::SetDouble( Int_t parameterIndex,Double_t x )
0299 {
0300    // Sets the designated parameter to a  double value. The
0301    // driver converts this to an SQL DOUBLE value when it sends it
0302    // to the database.
0303    //
0304    //   Parameters:
0305    //         parameterIndex - the first parameter is 1, 
0306    //                          the second is 2, ...
0307    //         x - the parameter value
0308    //   Throws:
0309    //         TSQLException - if a database access error occurs
0310    
0311    if(!fImp) { Destroyed();   return; } 
0312    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0313    
0314    try {
0315       imp->setDouble(parameterIndex,x);
0316 
0317    } catch(odbc::SQLException& e) {
0318       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0319                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0320                                 e.getErrorCode()) );
0321    }
0322 }
0323 
0324 //___________________________________________________________________
0325 void ODBCPreparedStatement::SetString( Int_t parameterIndex, 
0326                                        const TString& x )
0327 {
0328    //  Sets the designated parameter to a  TString value. The
0329    //  driver converts this to an SQL VARCHAR or LONGVARCHAR value
0330    //  (depending on the argument's size relative to the driver's
0331    //  limits on VARCHARs) when it sends it to the database.
0332    //
0333    //   Parameters:
0334    //         parameterIndex - the first parameter is 1, 
0335    //                          the second is 2, ...
0336    //         x - the parameter value
0337    //   Throws:
0338    //         TSQLException - if a database access error occurs
0339    
0340    if(!fImp) { Destroyed();   return; } 
0341    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0342    
0343    try {
0344       imp->setString( parameterIndex, ODBCXX_STRING_C(x.Data()) );
0345 
0346    } catch(odbc::SQLException& e) {
0347       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0348                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0349                                 e.getErrorCode()) );
0350    }
0351 }
0352 
0353 //___________________________________________________________________
0354 void ODBCPreparedStatement::SetBytes( Int_t parameterIndex,
0355                                       const TArrayC& x )
0356 {
0357    // Sets the designated parameter to a  array of bytes. The
0358    // driver converts this to an SQL VARBINARY or LONGVARBINARY
0359    // (depending on the argument's size relative to the driver's
0360    // limits on VARBINARYs) when it sends it to the database.
0361    //
0362    //   Parameters:
0363    //         parameterIndex - the first parameter is 1, 
0364    //                          the second is 2, ...
0365    //         x - the parameter value
0366    //   Throws:
0367    //         TSQLException - if a database access error occurs
0368 
0369    if(!fImp) { Destroyed();   return; } 
0370    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0371    
0372    try {
0373       imp->setBytes( parameterIndex,
0374                      ODBCXX_BYTES_C(x.GetArray(),x.GetSize()) );
0375 
0376    } catch(odbc::SQLException& e) {
0377       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0378                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0379                                 e.getErrorCode()) );
0380    }
0381 }
0382 
0383 //___________________________________________________________________
0384 void ODBCPreparedStatement::SetDate( Int_t parameterIndex,
0385                                      const TSQLDate& x )
0386 {
0387    //  Sets the designated parameter to a TSQLDate value. The
0388    //  driver converts this to an SQL DATE value when it sends it
0389    //  to the database.
0390    //
0391    //   Parameters:
0392    //         parameterIndex - the first parameter is 1, 
0393    //                          the second is 2, ...
0394    //         x - the parameter value
0395    //   Throws:
0396    //         TSQLException - if a database access error occurs
0397    
0398    if(!fImp) { Destroyed();   return; } 
0399    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0400    
0401    try {
0402       odbc::Date dt( x.GetYear(),
0403                      x.GetMonth(),
0404                      x.GetDay() );
0405 
0406       imp->setDate(parameterIndex,dt);
0407 
0408    } catch(odbc::SQLException& e) {
0409       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0410                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0411                                 e.getErrorCode()) );
0412    }
0413 }
0414 
0415 //___________________________________________________________________
0416 void ODBCPreparedStatement::SetTime( Int_t parameterIndex,
0417                                      const TSQLTime& x )
0418 {
0419    // Sets the designated parameter to a TSQLTime value. The
0420    // driver converts this to an SQL TIME value when it sends it
0421    // to the database.
0422    //
0423    //   Parameters:
0424    //         parameterIndex - the first parameter is 1, 
0425    //                          the second is 2, ...
0426    //         x - the parameter value
0427    //   Throws:
0428    //         TSQLException - if a database access error occurs
0429    
0430    if(!fImp) { Destroyed();   return; } 
0431    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0432    
0433    try {
0434       odbc::Time tm( x.GetHour(),
0435                      x.GetMinute(),
0436                      x.GetSecond() );
0437 
0438       imp->setTime(parameterIndex,tm);
0439 
0440    } catch(odbc::SQLException& e) {
0441       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0442                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0443                                 e.getErrorCode()) );
0444    }
0445 }
0446 
0447 //___________________________________________________________________
0448 void ODBCPreparedStatement::SetTimestamp( Int_t parameterIndex,
0449                                           const TSQLTimestamp& x )
0450 {
0451    // Sets the designated parameter to a TSQLTimestamp value.
0452    // The driver converts this to an SQL TIMESTAMP value when it
0453    // sends it to the database.
0454    //
0455    //   Parameters:
0456    //         parameterIndex - the first parameter is 1,
0457    //                          the second is 2, ...
0458    //         x - the parameter value
0459    //   Throws:
0460    //         TSQLException - if a database access error occurs
0461    
0462    if(!fImp) { Destroyed();   return; } 
0463    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0464    
0465    try {
0466       odbc::Timestamp tmstmp( x.GetYear(),
0467                               x.GetMonth(),
0468                               x.GetDay(),
0469                               x.GetHour(),
0470                               x.GetMinute(),
0471                               x.GetSecond(),
0472                               x.GetNanos() );
0473 
0474       imp->setTimestamp(parameterIndex,tmstmp);
0475 
0476    } catch(odbc::SQLException& e) {
0477       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0478                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0479                                 e.getErrorCode()) );
0480    }
0481 }
0482 
0483 //___________________________________________________________________
0484 void ODBCPreparedStatement::SetAsciiStream( Int_t parameterIndex,
0485                                             TBuffer* x,
0486                                             Int_t length )
0487 {
0488   // Sets the designated parameter to the given input stream,
0489   // which will have the specified number of bytes. When a very
0490   // large ASCII value is input to a LONGVARCHAR parameter, it
0491   // may be more practical to send it via a TBuffer
0492   // will read the data from the stream as needed, until it
0493   // reaches end-of-file. The  driver will do any necessary
0494   // conversion from ASCII to the database char format. 
0495   //
0496   //    Parameters:
0497   //          parameterIndex - the first parameter is 1, 
0498   //                           the second is 2, ...
0499   //          x - the  input stream that contains the ASCII
0500   //              parameter value
0501   //          length - the number of bytes in the stream,
0502   //                   total size of buffer is by default. 
0503   //    Throws:
0504   //          TSQLException - if a database access error occurs
0505 
0506    if(!fImp) { Destroyed();   return; } 
0507    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0508    
0509    try {
0510       Int_t  xl = x->BufferSize()>length ? length : x->BufferSize();
0511       std::istringstream* s = new std::istringstream(x->Buffer()); 
0512       imp->setAsciiStream( parameterIndex,(std::istream*)s,xl );
0513 
0514    } catch(odbc::SQLException& e) {
0515       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0516                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0517                                 e.getErrorCode()) );
0518    }
0519 }
0520 
0521 //___________________________________________________________________
0522 void ODBCPreparedStatement::SetBinaryStream( Int_t parameterIndex,
0523                                              TBuffer* x,
0524                                              Int_t length )
0525 {
0526    // Sets the designated parameter to the given input stream,
0527    // which will have the specified number of bytes. When a very
0528    // large binary value is input to a LONGVARBINARY parameter, it
0529    // may be more practical to send it via a TBuffer.
0530    // will read the data from the stream as needed, until it
0531    // reaches end-of-file. 
0532    //
0533    //   Parameters:
0534    //         parameterIndex - the first parameter is 1, 
0535    //                          the second is 2, ...
0536    //         x - the input tream which contains the binary
0537    //                  parameter value
0538    //         length - the number of bytes in the stream
0539    //                   total size of buffer is by default. 
0540    //   Throws:
0541    //         TSQLException - if a database access error occurs
0542 
0543    if(!fImp) { Destroyed();   return; } 
0544    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0545    
0546    try {
0547       Int_t xl = x->BufferSize()>length ? length : x->BufferSize();
0548       std::string a(x->Buffer(),xl);
0549 
0550       std::istream* s = new std::istringstream(a);
0551 
0552       _vec_str_buf.push_back(boost::shared_ptr<std::istream>(s));
0553 
0554       imp->setBinaryStream( parameterIndex,s,xl );
0555    } catch(odbc::SQLException& e) {
0556       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0557                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0558                                 e.getErrorCode()) );
0559    }
0560 }
0561 
0562 //___________________________________________________________________
0563 void ODBCPreparedStatement::SetObject( Int_t parameterIndex,TObject* x )
0564 {
0565    // Sets the designated parameter to the given ROOT object
0566    //
0567    //   Parameters:
0568    //         parameterIndex - the first parameter is 1, 
0569    //                          the second is 2, ...
0570    //         x - the ROOT object
0571    //   Throws:
0572    //         TSQLException - if a database access error occurs
0573 
0574 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,0)
0575   TBuffer *b = new TBufferFile(TBuffer::kWrite);
0576 #else
0577   TBuffer *b = new TBuffer(TBuffer::kWrite);
0578 #endif
0579    b->WriteObject(x);
0580    SetBinaryStream(parameterIndex,b,b->BufferSize());
0581    //   b->DetachBuffer();
0582    delete b;
0583 }
0584 
0585 //___________________________________________________________________
0586 void ODBCPreparedStatement::ClearParameters()
0587 {
0588    // Clears the current parameter values immediately. 
0589    //
0590    //  In general, parameter values remain in force for repeated
0591    //  use of a TSQLStatement. Setting a parameter value 
0592    //  automatically clears its previous value. However, in some 
0593    //  cases it is useful to immediately release the resources used 
0594    //  by the current parameter values; this can be done by calling
0595    //  ClearParameters().
0596    //   
0597    //   Throws:
0598    //         TSQLException - if a database access error occurs
0599    
0600    if(!fImp) { Destroyed();   return; } 
0601    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0602    
0603    try {
0604       imp->clearParameters();
0605 
0606    } catch(odbc::SQLException& e) {
0607       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0608                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0609                                 e.getErrorCode()) );
0610    }
0611 }
0612 
0613 //___________________________________________________________________
0614 TSQLResultSet* ODBCPreparedStatement::ExecuteQuery( const TString& sql )
0615 {
0616    // Executes a SQL statement that returns a single TSQLResultSet
0617    //
0618    // This method also implicitly closes current TSQLResultSet 
0619    //
0620    // Returns:
0621    //       a TSLResultSet that contains the data produced by the query; 
0622    //       NULL - in case of error
0623    //
0624    //   Throws:
0625    //       TSQLException - if a database access error occurs
0626 
0627    if(!fImp) { Destroyed(); return 0; }
0628    odbc::Statement* stmt = (odbc::Statement*)fImp;
0629    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;  
0630    odbc::ResultSet* rs = 0; 
0631    ClearWarnings();
0632 
0633    if(fCurrentResult)  delete fCurrentResult;
0634 
0635    try {
0636       if(!sql.IsNull()) {
0637          rs = stmt->executeQuery(ODBCXX_STRING_C(sql.Data()));
0638       } else {
0639          rs = imp->executeQuery();
0640       }
0641    } catch(odbc::SQLException& e) {
0642       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0643                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0644                                 e.getErrorCode()) );
0645       if(rs) delete rs;
0646       fCurrentResult = 0;
0647       return 0;
0648    }
0649    
0650    return fCurrentResult = new ODBCResultSet(this,(void*)rs);;
0651 }
0652 
0653 //___________________________________________________________________
0654 Bool_t ODBCPreparedStatement::Execute( const TString& sql )
0655 {
0656    // Executes a SQL statement that may return multiple results.
0657    // Under some (uncommon) situations a single SQL statement may 
0658    // return multiple result sets and/or update counts. Normally you 
0659    // can ignore this unless you are (1) executing a stored
0660    // procedure that you know may return multiple results or (2) you 
0661    // are dynamically executing an unknown SQL string. The methods 
0662    // execute, GetMoreResults(), GetResultSet(), and GetUpdateCount()
0663    // let you navigate through multiple results.
0664    //  The execute method executes a SQL statement and indicates the 
0665    // form of the first result. You can then use GetResultSet() or
0666    // GetUpdateCount() to retrieve the result, and GetMoreResults() 
0667    // to move to any subsequent result(s).
0668    //
0669    // Parameters:
0670    //          sql - any SQL statement
0671    // Returns:
0672    //          kTRUE if the next result is a TSQLResultSet; 
0673    //          kFALSE if it is an update count or there are no more
0674    //          results
0675    // Throws:
0676    //            TSQLException - if a database access error occurs
0677    // See Also: 
0678    //       GetResultSet(), GetUpdateCount(), GetMoreResults()
0679   
0680    if(!fImp) { Destroyed(); return kFALSE; }
0681 
0682    Bool_t return_value = kFALSE;
0683    ClearWarnings();
0684    odbc::Statement* stmt = (odbc::Statement*)fImp;
0685    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0686  
0687    try {
0688       if(!sql.IsNull()) {
0689          return_value = (Bool_t)stmt->execute(ODBCXX_STRING_C(sql.Data()));  
0690       } else {
0691          return_value = imp->execute(); 
0692       }
0693    } catch(odbc::SQLException& e) {
0694       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0695                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0696                                 e.getErrorCode()) );
0697       return_value = kFALSE;
0698    }
0699    return return_value;
0700 }
0701 
0702 //___________________________________________________________________
0703 Int_t ODBCPreparedStatement::ExecuteUpdate( const TString& sql )
0704 {
0705    // Executes an SQL INSERT, UPDATE or DELETE statement. 
0706    // In addition, SQL statements that return nothing, 
0707    // such as SQL DDL statements, can be executed.
0708    //
0709    //  Parameters:
0710    //      sql - a SQL INSERT, UPDATE or DELETE statement or 
0711    //            a SQL statement that  returns nothing
0712    //
0713    //  Returns:
0714    //      either the row count for INSERT, UPDATE or DELETE or 
0715    //      0 for SQL statements that return nothing
0716    //  Throws:
0717    //      TSQLException - if a database access error occurs
0718    
0719    if(!fImp) { Destroyed(); return 0; }
0720 
0721    Int_t return_value = 0;
0722    ClearWarnings();
0723    odbc::Statement* stmt = (odbc::Statement*)fImp;
0724    odbc::PreparedStatement* imp = (odbc::PreparedStatement*)fImp;
0725 
0726    try {
0727       if(!sql.IsNull()) {
0728          return_value = stmt->executeUpdate(ODBCXX_STRING_C(sql.Data()));
0729       } else {
0730          return_value = imp->executeUpdate();
0731       }   
0732    } catch(odbc::SQLException& e) {
0733       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0734                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0735                                 e.getErrorCode()) );
0736       return_value = 0;
0737    }
0738    return return_value;
0739 }
0740 
0741 //___________________________________________________________________
0742 TSQLResultSet* ODBCPreparedStatement::GetResultSet()
0743 {
0744    // Returns the current result as a TSQLResultSet object. 
0745    // This method should be called only once per result.
0746    //
0747    // This method also implicitly closes any current TSQLResultSet 
0748    //   
0749    // Returns:
0750    //       the current result as a TSQLResultSet; null if the result 
0751    //       is an update count or there are no more results
0752    // Throws:
0753    //       TSQLException - if a database access error occurs
0754    // See Also: 
0755    //       Execute(const TString&)
0756    
0757    if(!fImp) { Destroyed(); return 0; }
0758    odbc::ResultSet* rs;
0759    odbc::Statement* stmt = (odbc::Statement*)fImp;
0760 
0761    if(fCurrentResult)  delete fCurrentResult;
0762 
0763    try {     
0764       rs = stmt->getResultSet(); 
0765    } catch(odbc::SQLException& e) {
0766       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0767                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0768                                 e.getErrorCode()) );
0769       if(rs) delete rs;
0770       fCurrentResult = 0;
0771       return 0;
0772    }
0773 
0774    return fCurrentResult = new ODBCResultSet(this,(void*)rs); 
0775 }   
0776 
0777 //___________________________________________________________________
0778 Int_t ODBCPreparedStatement::GetUpdateCount()
0779 {
0780    // Returns the current result as an update count; 
0781    // if there are no more results, -1 is returned.
0782    // This method should be called only once per result.
0783    //
0784    // Returns:
0785    //       the current result as an update count; -1 if it is a 
0786    //       TSQLResultSet or there are no more results
0787    // Throws:
0788    //       TSQLException - if a database access error occurs
0789    // See Also: 
0790    //       Execute(const TString&)
0791    
0792    if(!fImp) { Destroyed(); return 0; }
0793 
0794    Int_t return_value = 0;
0795    odbc::Statement* stmt = (odbc::Statement*)fImp;
0796       
0797    try {
0798       return_value = stmt->getUpdateCount();
0799    } catch(odbc::SQLException& e) {
0800       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0801                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0802                                 e.getErrorCode()) );
0803       return  0;
0804    }
0805    return return_value;
0806 }
0807 
0808 //___________________________________________________________________
0809 Bool_t ODBCPreparedStatement::GetMoreResults()
0810 {
0811    // Moves to a ODBCStatement's next result. It returns kTRUE if 
0812    // this result is a TSQLResultSet. 
0813    // 
0814    // There are no more results when 
0815    //       (!GetMoreResults() && (GetUpdateCount() == -1)
0816    //
0817    // Returns:
0818    //    kTRUE if the next result is a TSQLResultSet; 
0819    //    kFALSE if it is an update count or there are no more results
0820    //
0821    // Throws:
0822    //       TSQLException - if a database access error occurs
0823    // See Also: 
0824    //       Execute(const TString&)
0825 
0826    Bool_t return_value = kFALSE;
0827    
0828    if(!fImp) { Destroyed(); return return_value; }
0829    odbc::Statement* stmt = (odbc::Statement*)fImp;
0830       
0831    try {
0832       return_value = (Bool_t)stmt->getMoreResults();      
0833    } catch(odbc::SQLException& e) {
0834       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0835                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0836                                 e.getErrorCode()) );
0837       return  kFALSE;
0838    }
0839    return return_value;
0840 }
0841 
0842 //___________________________________________________________________
0843 Int_t ODBCPreparedStatement::GetMaxFieldSize()
0844 {
0845    // Returns the maximum number of bytes allowed for any column 
0846    // value. This limit is the maximum number of bytes that can be
0847    // returned for any column value. The limit applies only to 
0848    // kBINARY, kVARBINARY, kLONGVARBINARY, kCHAR, kVARCHAR, and 
0849    // kLONGVARCHAR columns (see TSQLTypes.h). If the limit is exceeded, 
0850    // the excess data  is silently discarded.
0851    //
0852    // Returns:
0853    //    the current max column size limit; zero means unlimited
0854    // Throws:
0855    //    TSQLException - if a database access error occurs
0856 
0857    if(!fImp) { Destroyed(); return 0; }
0858 
0859    Int_t return_value = 0;
0860    odbc::Statement* stmt = (odbc::Statement*)fImp;
0861    
0862    try {
0863       return_value = stmt->getMaxFieldSize();
0864    } catch(odbc::SQLException& e) {
0865       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0866                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0867                                 e.getErrorCode()) );
0868       return 0;
0869    }
0870    return return_value;
0871 }
0872 
0873 //___________________________________________________________________
0874 void ODBCPreparedStatement::SetMaxFieldSize( Int_t max )
0875 {
0876    // Sets the limit for the maximum number of bytes in a column to 
0877    // the given number of bytes. This is the maximum number of bytes 
0878    // that can be returned for any column value. This limit applies 
0879    // only to kBINARY, kVARBINARY, kLONGVARBINARY, kCHAR, kVARCHAR,
0880    // and kLONGVARCHAR fields (see TSQLTypes.h) . If the limit is exceeded, 
0881    // the excess  data is silently discarded. For maximum portability, 
0882    // use values greater than 256.
0883    //
0884    // Parameters:
0885    //       max - the new max column size limit; zero means unlimited
0886    // Throws:
0887    //       TSQLException - if a database access error occurs
0888    
0889    if(!fImp) { Destroyed(); return; }
0890    odbc::Statement* stmt = (odbc::Statement*)fImp;
0891    
0892    try {
0893       stmt->setMaxFieldSize(max);   
0894    } catch(odbc::SQLException& e) {
0895       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0896                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0897                                 e.getErrorCode()) );
0898    }
0899 }
0900 
0901 //___________________________________________________________________
0902 Int_t ODBCPreparedStatement::GetMaxRows()
0903 {
0904    // Retrieves the maximum number of rows that a TSQLResultSet can 
0905    // contain. If the limit is exceeded, the excess rows are silently 
0906    // dropped.
0907    //
0908    // Returns:
0909    //       the current max row limit; zero means unlimited
0910    // Throws:
0911    //       TSQLException - if a database access error occurs
0912 
0913    if(!fImp) { Destroyed(); return 0; }
0914 
0915    Int_t return_value = 0;
0916    odbc::Statement* stmt = (odbc::Statement*)fImp;
0917    
0918    try {
0919       return_value = stmt->getMaxRows();
0920    } catch(odbc::SQLException& e) {
0921       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0922                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0923                                 e.getErrorCode()) );
0924       return 0;
0925    }
0926    return return_value;
0927 }
0928 
0929 //___________________________________________________________________
0930 void ODBCPreparedStatement::SetMaxRows( Int_t max )
0931 {
0932    // Sets the limit for the maximum number of rows that any 
0933    // TSQLResultSet can contain to the given number. If the limit is 
0934    // exceeded, the excess rows are silently dropped.
0935    //
0936    // Parameters:
0937    //       max - the new max rows limit; zero means unlimited
0938    // Throws:
0939    //       TSQLException - if a database access error occurs
0940    
0941    if(!fImp) { Destroyed(); return; }
0942    odbc::Statement* stmt = (odbc::Statement*)fImp;
0943    
0944    try {
0945       stmt->setMaxRows(max);  
0946    } catch(odbc::SQLException& e) {
0947       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0948                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0949                                 e.getErrorCode()) );
0950    }
0951 }
0952 
0953 //___________________________________________________________________
0954 void ODBCPreparedStatement::SetEscapeProcessing( Bool_t enable )
0955 {
0956    // Sets escape processing on or off. If escape scanning is on 
0957    // (the default), the driver will do escape substitution before 
0958    // sending the SQL to the database.
0959    // 
0960    // Note:
0961    //    Since prepared statements have usually been parsed prior to 
0962    //    making this call, disabling escape processing for prepared 
0963    //    statements will have no effect.
0964    //
0965    // Parameters:
0966    //       enable - kTRUE to enable; kFALSE to disable
0967    // Throws:
0968    //       TSQLException - if a database access error occurs
0969    
0970    if(!fImp) { Destroyed(); return; }
0971    odbc::Statement* stmt = (odbc::Statement*)fImp;
0972    
0973    try {
0974       stmt->setEscapeProcessing(enable);
0975    } catch(odbc::SQLException& e) {
0976       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
0977                                 ODBCXX_STRING_CSTR(e.getSQLState()),
0978                                 e.getErrorCode()) );
0979    }
0980 }
0981 
0982 //___________________________________________________________________
0983 Bool_t ODBCPreparedStatement::GetEscapeProcessing()
0984 {
0985    //  Returns if escape processing is on or off. 
0986    // If escape scanning is on (the default), the driver will do escape 
0987    // substitution before  sending the SQL to the database.
0988    // 
0989    // Note:
0990    //    Since prepared statements have usually been parsed prior to 
0991    //    making this call, disabling escape processing for prepared 
0992    //    statements will have no effect.
0993    //
0994    // Parameters:
0995    //       enable - kTRUE to enable; kFALSE to disable
0996    // Throws:
0997    //       TSQLException - if a database access error occurs
0998 
0999    if(!fImp) { Destroyed(); return kFALSE; }   
1000 
1001    Bool_t return_value = kFALSE;
1002    odbc::Statement* stmt = (odbc::Statement*)fImp;
1003    
1004    try {
1005       return_value = stmt->getEscapeProcessing();
1006    } catch(odbc::SQLException& e) {
1007       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
1008                                 ODBCXX_STRING_CSTR(e.getSQLState()),
1009                                 e.getErrorCode()) );
1010       return kFALSE;
1011    }
1012    return return_value;
1013 }
1014 
1015 //___________________________________________________________________
1016 Int_t ODBCPreparedStatement::GetQueryTimeout()
1017 {
1018    // Retrieves the number of seconds the driver will wait for a
1019    // ODBCStatement to execute. If the limit is exceeded, a 
1020    // TSQLException is thrown.
1021    //
1022    // Returns:
1023    //    the current query timeout limit in seconds; zero means
1024    //    unlimited
1025    // Throws:
1026    //    TSQLException - if a database access error occurs
1027    
1028    Int_t return_value = 0;
1029    
1030    if(!fImp) { Destroyed(); return return_value; }
1031    odbc::Statement* stmt = (odbc::Statement*)fImp;
1032       
1033    try {
1034       return_value = stmt->getQueryTimeout();
1035    } catch(odbc::SQLException& e) {
1036       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
1037                                 ODBCXX_STRING_CSTR(e.getSQLState()),
1038                                 e.getErrorCode()) );
1039       return 0;
1040    }
1041    return return_value;
1042 }
1043 
1044 //___________________________________________________________________
1045 void ODBCPreparedStatement::SetQueryTimeout( Int_t seconds )
1046 {
1047    // Sets the number of seconds the driver will wait for a 
1048    // ODBCStatement to execute to the given number of seconds. 
1049    // If the limit is exceeded, a TSQLException is thrown.
1050    //
1051    // Parameters:
1052    //          seconds - the new query timeout limit in seconds; 
1053    //          zero means unlimited
1054    // Throws:
1055    //          TSQLException - if a database access error occurs
1056    
1057    if(!fImp) { Destroyed(); return; }
1058    odbc::Statement* stmt = (odbc::Statement*)fImp;
1059    
1060    try {
1061       stmt->setQueryTimeout(seconds);
1062    } catch(odbc::SQLException& e) {
1063       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
1064                                 ODBCXX_STRING_CSTR(e.getSQLState()),
1065                                 e.getErrorCode()) );
1066    }
1067 }
1068 
1069 //___________________________________________________________________
1070 void ODBCPreparedStatement::Cancel() 
1071 {
1072    // Cancels this statement object if both the DBMS and driver 
1073    // support aborting an SQL statement. This method can be used by 
1074    // one thread to cancel a statement that is being executed by 
1075    // another thread.
1076    //
1077    // Throws:
1078    //       TSQLException - if a database access error occurs
1079    
1080    if(!fImp) { Destroyed(); return; }
1081    odbc::Statement* stmt = (odbc::Statement*)fImp;
1082    
1083    try {
1084       stmt->cancel();
1085    } catch(odbc::SQLException& e) {
1086       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
1087                                 ODBCXX_STRING_CSTR(e.getSQLState()),
1088                                 e.getErrorCode()) );
1089    }
1090 }
1091 
1092 //___________________________________________________________________
1093 void ODBCPreparedStatement::Close()
1094 {
1095    // Avoid using this method. Use delete ODBCStatement instead.
1096    //
1097    //  Note: When a ODBCStatement is closed, its current 
1098    //       TSQLResultSet,  if one exists, is also closed.
1099    //
1100    //     Throws:
1101    //      TSQLException - if a database access error occurs
1102    
1103    if(!fImp) { Destroyed(); return; }
1104           
1105    try {    
1106       if(fCurrentResult)  { 
1107          delete fCurrentResult;
1108          fCurrentResult = 0;
1109       }
1110       ClearBatch();
1111       SafeDelete(fBatches);
1112 
1113       odbc::Statement* imp = (odbc::Statement*)fImp;
1114       if(imp) delete  imp;
1115    } catch(odbc::SQLException& e) {
1116       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
1117                                 ODBCXX_STRING_CSTR(e.getSQLState()),
1118                                 e.getErrorCode()) );
1119    }
1120    fImp = 0;
1121    Destroyed();
1122 }
1123 
1124 //___________________________________________________________________
1125 void ODBCPreparedStatement::SetCursorName( const TString& name )
1126 {
1127    // Defines the SQL cursor name that will be used by subsequent
1128    // ODBCStatement execute methods. This name can then be used in 
1129    // SQL positioned update/delete statements to identify the 
1130    // current row in the TSQLResultSet generated by this statement. 
1131    // If the database doesn't support positioned update/delete, 
1132    // this method is a noop. To insure that a cursor has the proper 
1133    // isolation level to support updates, the cursor's SELECT 
1134    // statement should be of the form 'SELECT FOR UPDATE ...'. If
1135    // the 'FOR UPDATE' phrase is omitted, positioned updates may 
1136    // fail. 
1137    //
1138    // Note: By definition, positioned update/delete execution must 
1139    //    be done by a different ODBCStatement than the one which 
1140    //    generated the TSQLResultSet being used for positioning.
1141    //    Also, cursor names must be unique within a connection.
1142    //
1143    // Parameters:
1144    //       name - the new cursor name, which must be unique within
1145    //       a connection
1146    // Throws:
1147    //       TSQLException - if a database access error occurs
1148    
1149    if(!fImp) { Destroyed(); return; }
1150    odbc::Statement* stmt = (odbc::Statement*)fImp;
1151    
1152    try {
1153       stmt->setCursorName(ODBCXX_STRING_C(name.Data()));
1154    } catch(odbc::SQLException& e) {
1155       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
1156                                 ODBCXX_STRING_CSTR(e.getSQLState()),
1157                                 e.getErrorCode()) );
1158    }
1159 }
1160 
1161 //___________________________________________________________________
1162 void ODBCPreparedStatement::SetFetchDirection( Int_t /* direction */ )
1163 {
1164    // Gives the driver a hint as to the direction in which the
1165    // rows in a result set will be processed. The hint applies only 
1166    // to result sets created using this statement object. 
1167    // The default value is TSQLResultSet::kTYPE_FORWARD_ONLY
1168    //
1169    // Note that this method sets the default fetch direction for 
1170    // result sets generated by this statement object.
1171    //
1172    // Parameters:
1173    //    direction - the initial direction for processing rows
1174    // Throws:
1175    //    TSQLException - if a database access error occurs or the 
1176    //                   given direction is not one of 
1177    // 
1178    
1179    if(!fImp) { Destroyed(); return; }
1180 }
1181 
1182 //___________________________________________________________________
1183 Int_t ODBCPreparedStatement::GetFetchDirection()
1184 {
1185    // Retrieves the direction for fetching rows from database
1186    // tables that is the default for result sets generated from this 
1187    // statement object. If this statement object has not set 
1188    // a fetch direction by calling the method SetFetchDirection(), 
1189    // the return value is implementation-specific.
1190    //
1191    // Returns:
1192    //       the default fetch direction for result sets generated 
1193    //       from this statement object
1194    // Throws:
1195    //       TSQLException - if a database access error occurs
1196 
1197    return 0;
1198 }
1199 
1200 //___________________________________________________________________
1201 void ODBCPreparedStatement::SetFetchSize( Int_t /* rows */ )
1202 {
1203    // Gives the driver a hint as to the number of rows that
1204    // should be fetched from the database when more rows are needed. 
1205    // The number of rows specified affects only result sets created 
1206    // using this statement. If the value specified is zero, then the
1207    // hint is ignored. The default value is zero.
1208    //
1209    // Parameters:
1210    //       rows - the number of rows to fetch
1211    // Throws:
1212    //       TSQLException - if a database access error occurs, or 
1213    //       the condition 0 <= rows <= GetMaxRows() is not satisfied.
1214    
1215    if(!fImp) { Destroyed(); return; }
1216 }
1217 
1218 //___________________________________________________________________
1219 Int_t ODBCPreparedStatement::GetFetchSize()
1220 {
1221    // Retrieves the number of result set rows that is the default 
1222    // fetch size for result sets generated from this ODBCStatement 
1223    // object. If this statement object has not set a fetch size
1224    // by calling the method SetFetchSize(), the return value is
1225    // implementation-specific.
1226    //
1227    // Returns:
1228    //       the default fetch size for result sets generated from 
1229    //       this statement object
1230    // Throws:
1231    //       TSQLException - if a database access error occurs
1232    
1233    Int_t return_value = 0;
1234    
1235    if(!fImp) { Destroyed(); return return_value; }
1236    odbc::Statement* stmt = (odbc::Statement*)fImp;
1237    
1238    try {
1239       return_value = stmt->getFetchSize();
1240    } catch(odbc::SQLException& e) {
1241       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
1242                                 ODBCXX_STRING_CSTR(e.getSQLState()),
1243                                 e.getErrorCode()) );
1244       return 0;
1245    }
1246    return return_value;
1247 }
1248 
1249 //___________________________________________________________________
1250 Int_t ODBCPreparedStatement::GetResultSetConcurrency()
1251 {
1252    // Retrieves the result set concurrency.
1253    //
1254    // enum EResultSetConcurrency{
1255    //       kCONCUR_READ_ONLY,
1256    //       kCONCUR_UPDATABLE
1257    //    };
1258 
1259    Int_t return_value = 0;
1260    
1261    if(!fImp) { Destroyed(); return return_value; }
1262    odbc::Statement* stmt = (odbc::Statement*)fImp;
1263    
1264    try {
1265       return_value = stmt->getResultSetConcurrency();
1266    } catch(odbc::SQLException& e) {
1267       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
1268                                 ODBCXX_STRING_CSTR(e.getSQLState()),
1269                                 e.getErrorCode()) );
1270       return 0;
1271    }   
1272    return return_value;
1273 }
1274 
1275 //___________________________________________________________________
1276 Int_t ODBCPreparedStatement::GetResultSetType()
1277 {
1278    // Determine the result set type.
1279    //
1280    // enum EResultSetType{
1281    //       kTYPE_FORWARD_ONLY,
1282    //       kTYPE_SCROLL_INSENSITIVE,
1283    //       kTYPE_SCROLL_SENSITIVE
1284    //       };
1285    //
1286      
1287    Int_t return_value = 0;
1288    
1289    if(!fImp) { Destroyed(); return return_value; }
1290    odbc::Statement* stmt = (odbc::Statement*)fImp;
1291    
1292    try {
1293       return_value = stmt->getResultSetType(); 
1294    } catch(odbc::SQLException& e) {
1295       Throw( new TSQLException( ODBCXX_STRING_CSTR(e.getMessage()),
1296                                 ODBCXX_STRING_CSTR(e.getSQLState()),
1297                                 e.getErrorCode()) );
1298       return 0;
1299    }
1300    return return_value;
1301 }
1302 
1303 //___________________________________________________________________
1304 void ODBCPreparedStatement::AddBatch( const TString& /* sql */)
1305 {
1306    // Adds a SQL command to the current batch of commmands for
1307    // the statement. This method is optional.
1308    //
1309    // Parameters:
1310    //       sql - typically this is a static SQL INSERT or UPDATE 
1311    //       statement
1312    // Throws:
1313    //       TSQLException - if a database access error occurs, or 
1314    //       the  driver does not support batch statements
1315 
1316 }
1317 
1318 //___________________________________________________________________
1319 void ODBCPreparedStatement::ClearBatch()
1320 {
1321    // Makes the set of commands in the current batch empty. This
1322    // method is optional.
1323    //
1324    // Throws:
1325    //       TSQLException - if a database access error occurs or 
1326    //       the driver does not support batch statements
1327 
1328 }
1329 
1330 //___________________________________________________________________
1331 Int_t* ODBCPreparedStatement::ExecuteBatch()
1332 {
1333    // Submits a batch of commands to the database for execution.
1334    // This method is optional.
1335    //
1336    // Returns:
1337    //       an array of update counts containing one element for 
1338    //       each command in the batch. The array is ordered 
1339    //       according  to the order in which commands were inserted 
1340    //       into the  batch.
1341    //
1342    // Throws:
1343    //       TSQLException - if a database access error occurs or 
1344    //       the driver  does not support batch statements
1345 
1346    return 0;
1347 }