3 // Description: Statement Handle manager.
5 #include "odbcCommon.h"
8 CSqlOdbcStmt::CSqlOdbcStmt( void ) :
9 handleType_( SQL_HANDLE_STMT
),
12 err_( SQL_HANDLE_STMT
),
14 isParamBound_( true ),
22 //fetchMode_(SQL_FETCH_SINGLE_TUPLE)
24 cursorName_
[0] = '\0';
27 SQLRETURN
SQLAllocStmt(
28 SQLHDBC ConnectionHandle
,
29 SQLHSTMT
*StatementHandle
)
31 return( CSqlOdbcStmt::SQLAllocHandle( ConnectionHandle
, StatementHandle
) );
34 SQLRETURN
CSqlOdbcStmt::SQLAllocHandle(
35 SQLHANDLE inputHandle
, // IN
36 SQLHANDLE
*outputHandle
) // OUT
38 CSqlOdbcDbc
*inputDbc
= (CSqlOdbcDbc
*) inputHandle
;
41 if( isValidHandle( inputDbc
, SQL_HANDLE_DBC
) != SQL_SUCCESS
)
42 return( SQL_INVALID_HANDLE
);
45 if( inputDbc
->state_
< C4
)
47 globalError
.set( ERROR_CONNOTOPEN
);
48 globalError
.printStr( SQL_OV_ODBC3
);
52 // Allocate Statement object.
53 *outputHandle
= (SQLHANDLE
*) new CSqlOdbcStmt
;
54 if( *outputHandle
== NULL
)
56 globalError
.set( ERROR_MEMALLOC
);
57 globalError
.printStr( SQL_OV_ODBC3
);
61 // Initialize relation b/w Stmt and Dbc
62 inputDbc
->stmtList_
.insert( inputDbc
->stmtList_
.begin(), (CSqlOdbcStmt
*) *outputHandle
);
63 inputDbc
->stmtHdlList_
.append(outputHandle
);
64 if( inputDbc
->state_
<= C4
)
65 inputDbc
->state_
= C5
;
66 ((CSqlOdbcStmt
*) *outputHandle
)->parentDbc_
= inputDbc
;
67 //CSqlOdbcError::printDbg("proxy:stmt:setConnection");
68 //((CSqlOdbcStmt*) *outputHandle)->fsqlStmt_->setConnection( inputDbc->fsqlConn_ );
70 return( SQL_SUCCESS
);
73 SQLRETURN
CSqlOdbcStmt::SQLFreeHandle(
74 SQLHANDLE inputHandle
) // IN
76 CSqlOdbcStmt
*inputStmt
= (CSqlOdbcStmt
*) inputHandle
;
79 if( isValidHandle( inputStmt
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
80 return( SQL_INVALID_HANDLE
);
83 if( inputStmt
->chkStateForSQLFreeHandle() != SQL_SUCCESS
)
87 inputStmt
->resetStmt();
89 // Remove Stmt from Parent Dbc.
90 std::vector
<CSqlOdbcStmt
*>::iterator iter
;
91 iter
= inputStmt
->parentDbc_
->stmtList_
.begin();
92 while( iter
!= inputStmt
->parentDbc_
->stmtList_
.end() )
94 if( *iter
== inputStmt
)
96 inputStmt
->parentDbc_
->stmtList_
.erase( iter
);
101 // Set Dbc state_ = no statement.
102 if( inputStmt
->parentDbc_
->stmtList_
.size() == 0 )
103 inputStmt
->parentDbc_
->state_
= C4
;
105 inputStmt
->handleType_
= -1; // Make object invalid.
107 ListIterator it
= inputStmt
->parentDbc_
->stmtHdlList_
.getIterator();
108 while (it
.hasElement()) {
109 elem
= (SQLHANDLE
*) it
.nextElement();
110 if(*elem
== inputStmt
) *elem
= NULL
;
112 inputStmt
->parentDbc_
->stmtHdlList_
.remove(elem
);
113 delete inputStmt
; // Delete Stmt.
114 return( SQL_SUCCESS
);
117 SQLRETURN
SQLFreeStmt(
118 SQLHSTMT StatementHandle
, // IN
119 SQLUSMALLINT Option
) // IN
122 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
123 return( SQL_INVALID_HANDLE
);
126 if( Option
== SQL_DROP
)
127 return( CSqlOdbcStmt::SQLFreeHandle( StatementHandle
) );
129 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLFreeStmt( Option
) );
132 SQLRETURN
CSqlOdbcStmt::SQLFreeStmt(
139 if( chkStateForSQLFreeStmt() != SQL_SUCCESS
)
141 if (!fsqlStmt_
) return (SQL_SUCCESS
);
144 case SQL_CLOSE
: // // Free resultset
145 // if( fsqlStmt_->isSelect() == true ) // CSQL
147 // //CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
148 // CSqlResultSet *resultSet_ = fsqlStmt_->getResultSet(); // CSQL
149 // if( resultSet_ && resultSet_->isOpen() == true )
151 // resultSet_->close();
158 if( fsqlStmt_
->isSelect() == true ) // CSQL
159 state_
= S3
; // With Cursor
161 state_
= S2
; // Without Cursor
169 fsqlStmt_
->free(); // CSQL
175 case SQL_UNBIND
: ard_
.freeAllDesc();
179 case SQL_RESET_PARAMS
: apd_
.freeAllDesc();
181 //isParamBound_ = false;
184 default: err_
.set( ERROR_OPTRANGE
);
187 return( SQL_SUCCESS
);
190 SQLRETURN
SQLBindCol(
191 SQLHSTMT StatementHandle
,
192 SQLUSMALLINT ColumnNumber
,
193 SQLSMALLINT TargetType
,
194 SQLPOINTER TargetValue
,
195 SQLINTEGER BufferLength
,
196 SQLINTEGER
*StrLen_or_Ind
)
199 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
200 return( SQL_INVALID_HANDLE
);
202 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLBindCol( ColumnNumber
,
203 TargetType
, TargetValue
, BufferLength
, StrLen_or_Ind
) );
206 SQLRETURN
CSqlOdbcStmt::SQLBindCol(
207 SQLUSMALLINT columnNumber
,
208 SQLSMALLINT targetType
,
209 SQLPOINTER targetValue
,
210 SQLINTEGER bufferLength
,
213 CSqlOdbcDesc
*bindDesc
= 0;
214 CSqlOdbcDesc
*inputDesc
= 0;
215 SQLRETURN found
= SQL_ERROR
;
221 if( chkStateForSQLBindCol() != SQL_SUCCESS
)
224 // Invalid Buffer Length.
227 // switch is in order to support more types.
229 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
231 err_
.set( ERROR_BUFLEN
);
236 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
238 err_
.set( ERROR_BUFLEN
);
244 // Invalid Column Number
245 if( columnNumber
< 1 )
247 err_
.set( ERROR_COLNUM
);
251 // Get the Descriptor if already exists
252 found
= ard_
.getDescWithColNum( columnNumber
, &bindDesc
);
255 if( targetValue
== 0 )
257 if( found
!= SQL_SUCCESS
)
259 err_
.set( ERROR_COLNUM
);
262 ard_
.delDesc( bindDesc
); // UNBIND
264 return( SQL_SUCCESS
);
267 // Validate target Type, Value and Column no.
268 if( targetValue
== 0 || isValidCType( targetType
) != SQL_SUCCESS
)
270 err_
.set( ERROR_INVBUFTYPE
);
274 // Add new descriptor
275 if( found
!= SQL_SUCCESS
)
277 bindDesc
= new CSqlOdbcDesc();
278 ard_
.insert( ard_
.begin(), bindDesc
);
281 // Initialize Descriptor.
282 bindDesc
->col_
= columnNumber
;
283 bindDesc
->cType_
= targetType
;
284 bindDesc
->dataPtr_
= targetValue
;
285 bindDesc
->length_
= (SQLUINTEGER
) bufferLength
;
286 bindDesc
->indPtr_
= (SQLPOINTER
) ind
;
288 found
= ird_
.getDescWithColNum( columnNumber
, &inputDesc
);
290 // Add new descriptor
291 if( found
!= SQL_SUCCESS
)
293 inputDesc
= new CSqlOdbcDesc();
294 ird_
.insert(ird_
.begin(),inputDesc
);
297 //Get Field Information from CSQL
298 FieldInfo
*info
= new FieldInfo();
299 fsqlStmt_
->getProjFldInfo(columnNumber
, info
);
300 // Initialize input Descriptor.
301 //DataType sourceType = getCSqlType( targetType );
302 inputDesc
->col_
= columnNumber
;
303 inputDesc
->cType_
= info
->type
;
304 getInputBuffer(&inputDesc
->dataPtr_
,info
->type
,(SQLUINTEGER
) bufferLength
);
305 inputDesc
->length_
= info
->length
;
306 inputDesc
->indPtr_
= (SQLPOINTER
) ind
;
308 return( SQL_SUCCESS
);
311 SQLRETURN
SQLSetParam(
312 SQLHSTMT StatementHandle
,
313 SQLUSMALLINT ParameterNumber
,
314 SQLSMALLINT ValueType
,
315 SQLSMALLINT ParameterType
,
316 SQLUINTEGER LengthPrecision
,
317 SQLSMALLINT ParameterScale
,
318 SQLPOINTER ParameterValue
,
319 SQLINTEGER
*StrLen_or_Ind
)
321 return( SQLBindParameter( StatementHandle
, ParameterNumber
,
322 SQL_PARAM_INPUT_OUTPUT
, ValueType
, ParameterType
, LengthPrecision
,
323 ParameterScale
, ParameterValue
, 0, StrLen_or_Ind
) );
326 SQLRETURN
SQLBindParam(
327 SQLHSTMT StatementHandle
,
328 SQLUSMALLINT ParameterNumber
,
329 SQLSMALLINT ValueType
,
330 SQLSMALLINT ParameterType
,
331 SQLUINTEGER LengthPrecision
,
332 SQLSMALLINT ParameterScale
,
333 SQLPOINTER ParameterValue
,
334 SQLINTEGER
*StrLen_or_Ind
)
336 return( SQLBindParameter( StatementHandle
, ParameterNumber
,
337 SQL_PARAM_INPUT_OUTPUT
, ValueType
, ParameterType
, LengthPrecision
,
338 ParameterScale
, ParameterValue
, 0, StrLen_or_Ind
) );
341 SQLRETURN
SQLBindParameter(
342 SQLHSTMT StatementHandle
,
343 SQLUSMALLINT ParameterNumber
,
344 SQLSMALLINT InputOutputType
,
345 SQLSMALLINT ValueType
,
346 SQLSMALLINT ParameterType
,
347 SQLUINTEGER LengthPrecision
,
348 SQLSMALLINT ParameterScale
,
349 SQLPOINTER ParameterValue
,
350 SQLINTEGER BufferLength
,
351 SQLINTEGER
*StrLen_or_Ind
)
354 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
355 return( SQL_INVALID_HANDLE
);
357 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLBindParameter( ParameterNumber
,
358 InputOutputType
, ValueType
,
359 ParameterType
, LengthPrecision
,
360 ParameterScale
, ParameterValue
,
361 BufferLength
, StrLen_or_Ind
) );
364 SQLRETURN
CSqlOdbcStmt::SQLBindParameter(
365 SQLUSMALLINT parameterNumber
,
366 SQLSMALLINT inputOutputType
,
367 SQLSMALLINT valueType
,
368 SQLSMALLINT parameterType
,
369 SQLUINTEGER lengthPrecision
,
370 SQLSMALLINT parameterScale
,
371 SQLPOINTER parameterValue
,
372 SQLINTEGER bufferLength
,
375 CSqlOdbcDesc
*bindDesc
= 0;
376 CSqlOdbcDesc
*inputDesc
=0;
383 if( chkStateForSQLBindParameter() != SQL_SUCCESS
)
386 // Invalid Buffer Length.
389 // switch is in order to support more types.
391 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
393 err_
.set( ERROR_BUFLEN
);
398 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
400 err_
.set( ERROR_BUFLEN
);
406 // Validate parameters
407 switch( inputOutputType
)
409 case SQL_PARAM_INPUT
:
410 case SQL_PARAM_OUTPUT
:
411 case SQL_PARAM_INPUT_OUTPUT
: break;
412 default: err_
.set( ERROR_INV_PARAMTYPE
);
415 if( isValidCType( valueType
) != SQL_SUCCESS
||
416 isValidSQLType( parameterType
) != SQL_SUCCESS
)
418 err_
.set( ERROR_INVBUFTYPE
);
421 if( parameterNumber
< 1 )
423 err_
.set( ERROR_COLNUM
);
427 // Get the Descriptor if already exists
428 found
= apd_
.getDescWithColNum( parameterNumber
, &bindDesc
);
429 if( found
!= SQL_SUCCESS
)
431 bindDesc
= new CSqlOdbcDesc();
432 apd_
.insert( apd_
.end(), bindDesc
);
433 // Initialize Descriptor.
434 bindDesc
->col_
= parameterNumber
;
435 bindDesc
->paramType_
= inputOutputType
;
436 bindDesc
->cType_
= valueType
;
437 bindDesc
->sqlType_
= parameterType
;
438 bindDesc
->dataPtr_
= parameterValue
;
439 bindDesc
->length_
= (SQLUINTEGER
) bufferLength
;
440 bindDesc
->precision_
=(short) lengthPrecision
;
441 bindDesc
->scale_
= parameterScale
;
442 bindDesc
->indPtr_
= (SQLPOINTER
) ind
;
444 found
= ipd_
.getDescWithColNum (parameterNumber
, &inputDesc
);
445 if( found
!= SQL_SUCCESS
)
447 inputDesc
= new CSqlOdbcDesc();
448 ipd_
.insert(ipd_
.end(),inputDesc
);
449 //Initialize inputDescriptor
450 DataType destType
=getCSqlType(valueType
);
451 inputDesc
->col_
= parameterNumber
;
452 inputDesc
->paramType_
= inputOutputType
;
453 inputDesc
->cType_
= valueType
;
454 inputDesc
->sqlType_
= parameterType
;
455 inputDesc
->dataPtr_
= NULL
;
456 //getInputBuffer(&inputDesc->dataPtr_,destType,(SQLUINTEGER)bufferLength);
457 inputDesc
->length_
= (SQLUINTEGER
) bufferLength
;
458 inputDesc
->precision_
= (short)lengthPrecision
;
459 inputDesc
->scale_
= parameterScale
;
460 inputDesc
->indPtr_
= (SQLPOINTER
) ind
;
462 //isParamBound_ = false;
463 return( SQL_SUCCESS
);
466 SQLRETURN
SQLPrepare(
467 SQLHSTMT StatementHandle
, // IN
468 SQLCHAR
*StatementText
, // IN
469 SQLINTEGER TextLength
) // IN
472 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
473 return( SQL_INVALID_HANDLE
);
476 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLPrepare( StatementText
, TextLength
) );
479 SQLRETURN
CSqlOdbcStmt::SQLPrepare(
480 SQLCHAR
*statementText
, // IN
481 SQLINTEGER textLength
) // IN
487 if( chkStateForSQLPrepare() != SQL_SUCCESS
)
490 // Invalid Buffer Length.
491 if( textLength
< 0 && textLength
!= SQL_NTS
)
493 err_
.set( ERROR_BUFLEN
);
497 // If Stmt is already prepared.
502 if (parentDbc_
->mode_
==1)
503 fsqlStmt_
= SqlFactory::createStatement(CSql
);
504 else if (parentDbc_
->mode_
==2)
505 fsqlStmt_
= SqlFactory::createStatement(CSqlGateway
);
506 else if (parentDbc_
->mode_
==3)
507 fsqlStmt_
= SqlFactory::createStatement(CSqlAdapter
);
508 fsqlStmt_
->setConnection( parentDbc_
->fsqlConn_
);
511 //CSqlOdbcError::printDbg("proxy:stmt:prepare");
513 if( (rv
=fsqlStmt_
->prepare( (char*) statementText
))!= OK
) // CSQL
516 err_
.set(ERROR_GENERAL
);
519 case csqlSqlErrSchNotFound: err_.set( ERROR_SCHNOTFOUND); break;
520 case csqlSqlErrTblNotFound: err_.set( ERROR_TBLNOTFOUND); break;
521 case csqlSqlErrFldNotFound: err_.set( ERROR_NO_COLEXISTS); break;
522 case csqlSqlErrIndexNotFound: err_.set( ERROR_NO_IDXEXISTS); break;
523 case csqlSqlErrViewNotFound: err_.set( ERROR_TBLNOTFOUND); break;
524 case csqlSqlErrTblExists: err_.set( ERROR_TBLEXISTS); break;
525 case csqlSqlErrFldExists: err_.set( ERROR_COLEXISTS); break;
526 case csqlSqlErrIndexExists: err_.set( ERROR_IDXEXISTS); break;
527 case csqlSqlErrViewExists: err_.set( ERROR_TBLEXISTS); break;
528 case csqlSqlErrTooManyVals:err_.set(ERROR_MANY_VALS);break;
529 case csqlSqlErrTooFewVals:err_.set(ERROR_FEW_VALS);break;
530 case csqlSqlErrSqlSyntaxError:err_.set(ERROR_SQL_SYNTAX);break;
531 case csqlSqlErrIncompatibleType:err_.set(ERROR_TYPE_INCMP);break;
532 case csqlSqlErrInvalidFormat:err_.set(ERROR_DATA_FORMAT);break;
533 case csqlSqlErrDuplicateFld:err_.set(ERROR_DUP_COL);break;
534 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
539 if( fsqlStmt_
->isSelect() != true ) // CSQL
540 state_
= S2
; // With cursor
542 state_
= S3
; // Without cursor
544 //parentDbc_->state_ = C6;
546 return( SQL_SUCCESS
);
549 SQLRETURN
SQLExecute(SQLHSTMT StatementHandle
) // IN
552 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
553 return( SQL_INVALID_HANDLE
);
555 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLExecute() );
558 SQLRETURN
CSqlOdbcStmt::SQLExecute() // TODO
564 if( chkStateForSQLExecute() != SQL_SUCCESS
)
567 if( fsqlStmt_
->noOfParamFields() > 0 )
570 // Iterate through all apd_;
571 CSqlOdbcDesc
*appParamDesc
;
572 CSqlOdbcDescList::iterator apdIter
;
573 apdIter
= apd_
.begin();
574 CSqlOdbcDesc
*csqlParamDesc
;
575 CSqlOdbcDescList::iterator ipdIter
;
576 ipdIter
= ipd_
.begin();
578 //Get the source and the destination type
579 DataType sourceType
= typeUnknown
,destType
= typeUnknown
;
580 int paramNum
=1,sourceLength
=-1,destLength
=-1;
583 while( (apdIter
!= apd_
.end()) || (ipdIter
!= ipd_
.end()) )
585 appParamDesc
=*apdIter
;
586 csqlParamDesc
=*ipdIter
;
587 if((paramNum
) <= fsqlStmt_
->noOfParamFields())
589 FieldInfo
*finfo
= new FieldInfo();
590 if( fsqlStmt_
->getParamFldInfo(paramNum
, finfo
) != OK
) return( SQL_ERROR
);
591 sourceType
=getCSqlType(appParamDesc
->cType_
);
592 destType
=finfo
->type
;
593 sourceLength
=(int)appParamDesc
->length_
;
594 destLength
=finfo
->length
;
596 if(sourceType
!= typeUnknown
&& destType
!= typeUnknown
)
598 //Check if NULL is inserted
599 if((appParamDesc
->indPtr_
!= NULL
) && (*(SQLINTEGER
*)appParamDesc
->indPtr_
) == SQL_NULL_DATA
)
602 //finfo->isNull = true; CSQL TODO - need to understand how to set null
606 //Only if both types are not the same, then we need to copy it onto intermediate buffer
608 if( (sourceType
== typeString
|| sourceType
== typeBinary
) && (sourceLength
<= 0))
610 if((appParamDesc
->indPtr_
!= NULL
) && *(SQLINTEGER
*)appParamDesc
->indPtr_
> 0)
611 sourceLength
=(int)(*(SQLINTEGER
*)appParamDesc
->indPtr_
);
612 else if (appParamDesc
->precision_
> 0)
613 sourceLength
=appParamDesc
->precision_
;
616 err_
.set( ERROR_BUFLEN
);
620 if(destType
== typeString
) //|| destType == typeVarString)
622 //fsqlStmt_->allocParam(paramNum,sourceLength); // CSQL TODO
623 destLength
=sourceLength
;
625 if(sourceType
== destType
)
626 //|| (sourceType == typeString && destType == typeVarString)
627 //|| (sourceType == typeBinary && destType == typeVarBinary))
629 copyFromOdbc(fsqlStmt_
, paramNum
, destLength
, appParamDesc
->dataPtr_
, sourceLength
,destType
); // CSQL TODO
632 getInputBuffer(&csqlParamDesc
->dataPtr_
,sourceType
,sourceLength
);
633 copyFromOdbc(fsqlStmt_
, paramNum
, destLength
, appParamDesc
->dataPtr_
, sourceLength
, sourceType
);
634 //convert(sourceType,csqlParamDesc->dataPtr_,destType, fsqlStmt_->getParamPtr( paramNum),sourceLength,destLength); // CSQL TODO
640 err_
.set(ERROR_GENERAL
);
653 DbRetVal rv
= fsqlStmt_
->execute( rowsAffected
);
654 if( rowsAffected
< 0 )
656 if( isPrepared_
) state_
= S2
; else resetStmt();
657 err_
.set( ERROR_GENERAL
);
660 case csqlSqlErrOverflow:err_.set(ERROR_OVERFLOW);break;
661 case csqlSqlErrUnderflow:err_.set(ERROR_UNDERFLOW);break;
662 case csqlSqlErrTooManyTpl:err_.set(ERROR_MANY_TUP);break;
663 case csqlSqlErrProjCnt:err_.set(ERROR_NUM_PROJ);break;
664 case csqlSqlErrStorageAttr:err_.set(ERROR_STORAGE_ATTR);break;
665 case csqlSqlErrFldCntMismatch:err_.set(ERROR_FLDCNT_MISMATCH);break;
666 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
667 case csqlSqlErrNoMatchKeyFound:err_.set(ERROR_MATCHKEY_NOTFOUND);break;
669 err_.set( ERROR_GENERAL );break;
675 if( fsqlStmt_
->isSelect() == true )
682 rowsAffected_
= rowsAffected
;
686 // Set Dbc State to Transaction Mode.
687 parentDbc_
->state_
= C6
;
690 if( parentDbc_
->autoCommit_
== SQL_AUTOCOMMIT_ON
)
691 parentDbc_
->SQLEndTran( SQL_COMMIT
);
693 return( SQL_SUCCESS
);
696 SQLRETURN
SQLExecDirect(
697 SQLHSTMT StatementHandle
,
698 SQLCHAR
*StatementText
,
699 SQLINTEGER TextLength
)
702 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
703 return( SQL_INVALID_HANDLE
);
705 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLExecDirect( StatementText
, TextLength
) );
708 SQLRETURN
CSqlOdbcStmt::SQLExecDirect(
709 SQLCHAR
*statementText
,
710 SQLINTEGER textLength
)
715 if( chkStateForSQLExecDirect() != SQL_SUCCESS
)
718 // SQLExecDirect = SQLPrepare + SQLExecute.
719 if( SQLPrepare( statementText
, textLength
) != SQL_SUCCESS
)
723 isPrepared_
= false; // Set Stmt as non-prepared stmt.
725 if( ret
!= SQL_SUCCESS
)
728 return( SQL_SUCCESS
);
731 SQLRETURN
SQLSetStmtOption(
732 SQLHSTMT StatementHandle
,
736 return (SQLSetStmtAttr(StatementHandle
, Option
, (SQLPOINTER
) Value
, 0));
739 SQLRETURN SQL_API
SQLSetStmtAttr(SQLHSTMT StatementHandle
,
740 SQLINTEGER Attribute
, SQLPOINTER Value
,
741 SQLINTEGER StringLength
)
743 return (((CSqlOdbcStmt
*)StatementHandle
)->SQLSetStmtAttr(Attribute
, Value
,StringLength
));
746 SQLRETURN
CSqlOdbcStmt::SQLSetStmtAttr(
747 SQLINTEGER Attribute
,
749 SQLINTEGER stringLength
)
751 CSqlOdbcError::printDbg("proxy:stmt:SQLSetStmtAttr");
755 //Values: SQL_FETCH_SINGLE_TUPLE or SQL_FETCH_MULTIPLE_TUPLES
756 //Default is SQL_FETCH_SINGLE_TUPLE.
757 //In SQL_FETCH_SINGLE_TUPLE mode, only a single tuple
758 //is sent from server to client in a single packet whatever be
759 //the packet size. If a tuple size is 50 and network packet size
760 //is 500, the remaining 450 bytes can also be used to send more
761 //in a single packet so that in the next SQLFetch call one network
762 //packet transfer overhead is reduced.
765 //state_ > S5 means Fetch has already started on this statement.
766 fetchMode_ = (SQLINTEGER)Value;
768 printf("ODBC:Error in setting fetch mode, can't set after fetch is started.\n");
771 printf("ODBC: Error, Stmt Option %d is not supported.\n", Attribute);
773 return (SQL_SUCCESS
);
776 SQLRETURN
SQLFetch(SQLHSTMT StatementHandle
)
779 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
780 return( SQL_INVALID_HANDLE
);
782 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLFetch() );
785 SQLRETURN
CSqlOdbcStmt::SQLFetch()
791 if( chkStateForSQLFetch() != SQL_SUCCESS
)
795 tuple
= fsqlStmt_
->next();
797 if( ! tuple
) // IF Row not found.
801 return( SQL_NO_DATA_FOUND
);
803 /*else if( rowsAffected != SQL_SUCCESS ) // IF Error
806 err_.set( ERROR_GENERAL );
809 else // IF Row found.
813 // Iterate through all ard_;
814 CSqlOdbcDesc
*appColDesc
;
815 CSqlOdbcDescList::iterator ardIter
;
816 ardIter
= ard_
.begin();
817 //Get the input parameter data
818 CSqlOdbcDesc
*csqlColDesc
;
819 CSqlOdbcDescList::iterator irdIter
;
820 irdIter
= ird_
.begin();
822 DataType sourceType
= typeUnknown
,destType
= typeUnknown
;
823 int colNum
=-1,sourceLength
=-1,destLength
=-1;
825 void* sourceData
= NULL
;
826 //FieldInfo *info = new FieldInfo();
827 while( (ardIter
!= ard_
.end()) || (irdIter
!= ird_
.end()) )
829 appColDesc
= *ardIter
;
830 csqlColDesc
= *irdIter
;
832 colNum
= appColDesc
->col_
- 1;
833 // fsqlStmt_->getProjFldInfo(colNum+1, info);
834 sourceType
= (DataType
)csqlColDesc
->cType_
;
835 destType
= getCSqlType(appColDesc
->cType_
);
836 sourceLength
= (int)csqlColDesc
->length_
;
837 destLength
= (int)appColDesc
->length_
;
839 if( sourceType
!= typeUnknown
&& destType
!= typeUnknown
)
841 sourceData
= fsqlStmt_
->getFieldValuePtr( colNum
);
842 if(fsqlStmt_
->isFldNull(appColDesc
->col_
) || sourceData
== NULL
)
844 if (appColDesc
->indPtr_
!= NULL
)
845 *((SQLINTEGER
*)(appColDesc
->indPtr_
))=SQL_NULL_DATA
;
849 /*if( sourceType == csqlSqlTvarBinary)
850 sourceLength=resultSet_->getDataLength(colNum); */
851 if (sourceType
== typeString
) // CSQL TODO - handle varchar also
853 sourceLength
=(int)(strlen((char *) sourceData
));
854 if(appColDesc
->indPtr_
!= NULL
)
855 *((SQLINTEGER
*)(appColDesc
->indPtr_
))=copyToOdbc(appColDesc
->dataPtr_
,destLength
,
856 sourceData
,sourceLength
, sourceType
);
858 copyToOdbc(appColDesc
->dataPtr_
,destLength
,sourceData
,
859 sourceLength
, sourceType
);
863 //convert(sourceType,sourceData,destType, csqlColDesc->dataPtr_,sourceLength,destLength);
864 if(appColDesc
->indPtr_
!= NULL
){
865 *((SQLINTEGER
*)(appColDesc
->indPtr_
))=
866 copyToOdbc(appColDesc
->dataPtr_
,destLength
, sourceData
, sourceLength
, sourceType
);
869 copyToOdbc(appColDesc
->dataPtr_
,destLength
, sourceData
, sourceLength
, sourceType
);
872 // CSQL TODO - handle varstring, binary, varbinary
873 if( sourceType
== typeString
&& sourceLength
> destLength
)
874 err_
.set( ERROR_DATATRUNC
);
882 if(err_
.csqlErrCode
== ERROR_DATATRUNC
)
883 return (SQL_SUCCESS_WITH_INFO
);
885 return( SQL_SUCCESS
);
888 SQLRETURN
SQLCloseCursor(SQLHSTMT StatementHandle
)
891 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
892 return( SQL_INVALID_HANDLE
);
894 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLCloseCursor() );
897 SQLRETURN
CSqlOdbcStmt::SQLCloseCursor()
903 if( chkStateForSQLCloseCursor() != SQL_SUCCESS
)
909 return( SQL_SUCCESS
);
912 SQLRETURN
SQLSetCursorName(
913 SQLHSTMT StatementHandle
,
915 SQLSMALLINT NameLength
)
918 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
919 return( SQL_INVALID_HANDLE
);
921 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLSetCursorName( CursorName
, NameLength
) );
924 SQLRETURN
CSqlOdbcStmt::SQLSetCursorName(
926 SQLSMALLINT nameLength
)
932 if( chkStateForSQLSetCursorName() != SQL_SUCCESS
)
935 // Invalid Stmt Length.
936 if( nameLength
< 0 && nameLength
!= SQL_NTS
)
938 err_
.set( ERROR_INVARGVAL
);
942 // Validate Parameters
943 if( cursorName
== 0 || cursorName
[0] == '\0' || strlen( (char*) cursorName
) > SQL_MAX_CURSOR_NAME_LEN
||
944 nameLength
> SQL_MAX_CURSOR_NAME_LEN
)
946 err_
.set( ERROR_CURNAME
);
950 // Check for duplicate Name
951 std::vector
<CSqlOdbcStmt
*>::iterator iter
;
952 iter
= parentDbc_
->stmtList_
.begin();
953 while( iter
!= parentDbc_
->stmtList_
.end() )
957 if( strcmp( (char*) cursorName
, (char*) (*iter
)->cursorName_
) == 0 )
959 err_
.set( ERROR_DUP_CURNAME
);
967 strcpy( (char*) cursorName_
, (char*) cursorName
);
969 return( SQL_SUCCESS
);
972 SQLRETURN
SQLGetCursorName(
973 SQLHSTMT StatementHandle
,
975 SQLSMALLINT BufferLength
,
976 SQLSMALLINT
*NameLength
)
979 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
980 return( SQL_INVALID_HANDLE
);
982 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLGetCursorName( CursorName
, BufferLength
, NameLength
) );
984 SQLRETURN
CSqlOdbcStmt::SQLGetCursorName(
986 SQLSMALLINT bufferLength
,
987 SQLSMALLINT
*nameLength
)
990 if( chkStateForSQLGetCursorName() != SQL_SUCCESS
)
993 if( cursorName_
[0] == '\0' )
995 err_
.set( ERROR_NOCURNAME
);
1000 *nameLength
= (short)strlen( (char*) cursorName_
);
1001 if( *nameLength
> bufferLength
) *nameLength
= bufferLength
;
1002 strncpy( (char*) cursorName
, (char*) cursorName_
, *nameLength
);
1003 cursorName
[ *nameLength
] = '\0';
1006 if( bufferLength
< strlen( (char*) cursorName_
) )
1008 err_
.set( ERROR_DATATRUNC
);
1009 return( SQL_SUCCESS_WITH_INFO
);
1012 return( SQL_SUCCESS
);
1015 SQLRETURN
SQLNumResultCols(
1016 SQLHSTMT StatementHandle
, // IN
1017 SQLSMALLINT
*ColumnCount
) // OUT
1020 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1021 return( SQL_INVALID_HANDLE
);
1023 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLNumResultCols( ColumnCount
) );
1026 SQLRETURN
CSqlOdbcStmt::SQLNumResultCols(
1027 SQLSMALLINT
*columnCount
) // OUT
1029 // Start with NO_ERR
1033 if( chkStateForSQLNumResultCols() != SQL_SUCCESS
)
1034 return( SQL_ERROR
);
1037 if( fsqlStmt_
->isSelect() == false )
1040 return (SQL_SUCCESS
);
1044 SQLSMALLINT count
= fsqlStmt_
->noOfProjFields();
1045 if( count
< 1 ) // Assume atleast one column is projected
1046 return( SQL_ERROR
);
1048 // Fill Column Count
1049 *columnCount
= count
;
1051 return( SQL_SUCCESS
);
1054 SQLRETURN SQL_API
SQLRowCount(
1055 SQLHSTMT StatementHandle
, // IN
1056 SQLINTEGER
*RowCount
) // OUT
1059 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1060 return( SQL_INVALID_HANDLE
);
1062 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLRowCount( RowCount
) );
1065 SQLRETURN
CSqlOdbcStmt::SQLRowCount(
1066 SQLINTEGER
*rowCount
) // OUT
1068 // Start with NO_ERR
1072 if( chkStateForSQLRowCount() != SQL_SUCCESS
)
1073 return( SQL_ERROR
);
1075 if(rowCount
== NULL
)
1078 if( state_
== S4
) // For INSERT/DELETE/UPDATE
1079 *rowCount
= (SQLINTEGER
) rowsAffected_
;
1080 else if( state_
== S5
) // For SELECT before SQLFetch()
1082 *rowCount
= (SQLINTEGER
) 0;
1083 // CSQL TODO - Think if you really want to do this!!!
1085 /*CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
1086 CSqlResultSet *resultSet_ = fsqlStmt_.getResultSet();
1087 if( resultSet_->next() != csqlSqlErrNoTuple )
1088 *rowCount = (SQLINTEGER) 1;
1090 resultSet_->close();
1091 resultSet_->open(); */
1093 else if( state_
== S6
) // For SELECT after SQLFetch();
1094 *rowCount
= (SQLINTEGER
) rowsAffected_
;
1096 return( SQL_SUCCESS
);
1099 SQLRETURN
SQLDescribeCol(
1100 SQLHSTMT StatementHandle
,
1101 SQLUSMALLINT ColumnNumber
,
1102 SQLCHAR
*ColumnName
,
1103 SQLSMALLINT BufferLength
,
1104 SQLSMALLINT
*NameLength
,
1105 SQLSMALLINT
*DataType
,
1106 SQLUINTEGER
*ColumnSize
,
1107 SQLSMALLINT
*DecimalDigits
,
1108 SQLSMALLINT
*Nullable
)
1111 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1112 return( SQL_INVALID_HANDLE
);
1114 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLDescribeCol( ColumnNumber
, ColumnName
, BufferLength
,
1115 NameLength
, DataType
, ColumnSize
, DecimalDigits
, Nullable
) );
1118 SQLRETURN
CSqlOdbcStmt::SQLDescribeCol(
1119 SQLUSMALLINT columnNumber
,
1120 SQLCHAR
*columnName
,
1121 SQLSMALLINT bufferLength
,
1122 SQLSMALLINT
*nameLength
,
1123 SQLSMALLINT
*dataType
,
1124 SQLUINTEGER
*columnSize
,
1125 SQLSMALLINT
*decimalDigits
,
1126 SQLSMALLINT
*nullable
)
1134 // Start with NO_ERR
1138 if( chkStateForSQLDescribeCol() != SQL_SUCCESS
)
1139 return( SQL_ERROR
);
1141 if( columnNumber
< 1 )
1143 err_
.set( ERROR_COLNUM
);
1144 return( SQL_ERROR
);
1148 if( fsqlStmt_
->isSelect() == false )
1149 return( SQL_ERROR
);
1152 if(columnNumber
> fsqlStmt_
->noOfProjFields())
1154 err_
.set( ERROR_COLNUM
);
1155 return( SQL_ERROR
);
1157 if(columnName
== NULL
) {
1158 err_
.set( ERROR_COLNUM
);
1159 return( SQL_ERROR
);
1161 FieldInfo
*info
= new FieldInfo();
1162 fsqlStmt_
->getProjFldInfo(columnNumber
+1, info
);
1163 strncpy( (char*)columnName
, (char*)info
->fldName
, bufferLength
);
1164 if(nameLength
!= NULL
)
1165 *nameLength
=(short)strlen((const char*)info
->fldName
); // HARDCODED - TO DO, need support for n/w layer & sql layer
1166 if(dataType
!= NULL
)
1167 *dataType
= (SQLSMALLINT
) getSQLType(info
->type
); // Need to convert from SQL<->ODBC - TO DO
1168 if(columnSize
!= NULL
)
1170 *columnSize
= (SQLUINTEGER
) info
->length
;
1171 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1172 if(sqlType
== SQL_CHAR
)
1173 *columnSize
= *columnSize
-1;
1176 /*if(decimalDigits != NULL) // CSQL TODO
1177 *decimalDigits = (SQLSMALLINT) fsqlStmt_->getPrecision( columnNumber-1 );
1178 if(nullable != NULL)
1179 *nullable = rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N; */
1180 if(strlen((char*)info
->fldName
) > bufferLength
)
1182 err_
.set( ERROR_DATATRUNC
);
1183 return( SQL_SUCCESS_WITH_INFO
);
1186 return( SQL_SUCCESS
);
1189 SQLRETURN
SQLColAttributes(
1190 SQLHSTMT StatementHandle
,
1191 SQLUSMALLINT ColumnNumber
,
1192 SQLUSMALLINT FieldIdentifier
,
1193 SQLPOINTER CharacterAttributePtr
,
1194 SQLSMALLINT BufferLength
,
1195 SQLSMALLINT
*StringLengthPtr
,
1196 SQLINTEGER
*NumericAttributePtr
)
1199 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1200 return( SQL_INVALID_HANDLE
);
1202 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLColAttribute(ColumnNumber
,FieldIdentifier
,
1203 CharacterAttributePtr
, BufferLength
, StringLengthPtr
, (SQLPOINTER
)NumericAttributePtr
) );
1206 SQLRETURN
SQLColAttribute(
1207 SQLHSTMT StatementHandle
,
1208 SQLUSMALLINT ColumnNumber
,
1209 SQLUSMALLINT FieldIdentifier
,
1210 SQLPOINTER CharacterAttributePtr
,
1211 SQLSMALLINT BufferLength
,
1212 SQLSMALLINT
* StringLengthPtr
,
1213 SQLPOINTER NumericAttributePtr
)
1216 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1217 return( SQL_INVALID_HANDLE
);
1219 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLColAttribute(ColumnNumber
,FieldIdentifier
,
1220 CharacterAttributePtr
, BufferLength
, StringLengthPtr
, NumericAttributePtr
) );
1223 SQLRETURN
CSqlOdbcStmt::SQLColAttribute(
1224 SQLUSMALLINT columnNumber
,
1225 SQLUSMALLINT fieldIdentifier
,
1226 SQLPOINTER characterAttributePtr
,
1227 SQLSMALLINT bufferLength
,
1228 SQLSMALLINT
* stringLengthPtr
,
1229 SQLPOINTER numericAttributePtr
)
1237 // Start with NO_ERR
1241 if( chkStateForSQLDescribeCol() != SQL_SUCCESS
)
1242 return( SQL_ERROR
);
1244 if( columnNumber
< 1 )
1246 err_
.set( ERROR_COLNUM
);
1247 return( SQL_ERROR
);
1250 if( fsqlStmt_
->isSelect() == false )
1251 return( SQL_ERROR
);
1253 FieldInfo
*info
= new FieldInfo();
1254 fsqlStmt_
->getProjFldInfo(columnNumber
+1, info
);
1257 if(columnNumber
> fsqlStmt_
->noOfProjFields())
1259 err_
.set( ERROR_COLNUM
);
1260 return( SQL_ERROR
);
1262 switch(fieldIdentifier
)
1265 case SQL_COLUMN_NAME
:
1266 if(characterAttributePtr
!= NULL
)
1268 strncpy( (char*)characterAttributePtr
, (char*)info
->fldName
, bufferLength
);
1269 if(stringLengthPtr
!= NULL
)
1270 *stringLengthPtr
=(short)strlen((char*)info
->fldName
);
1273 case SQL_DESC_COUNT
:
1274 case SQL_COLUMN_COUNT
:
1275 if(numericAttributePtr
!= NULL
)
1276 *(SQLINTEGER
*)numericAttributePtr
=fsqlStmt_
->noOfProjFields();
1279 case SQL_COLUMN_TYPE
:
1280 if(numericAttributePtr
!= NULL
)
1281 *(SQLINTEGER
*)numericAttributePtr
=getSQLType(info
->type
);
1283 case SQL_DESC_LENGTH
:
1284 case SQL_COLUMN_LENGTH
:
1285 if(numericAttributePtr
!= NULL
)
1287 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1288 *(SQLINTEGER
*)numericAttributePtr
=(SQLUINTEGER
) info
->length
;
1289 if(sqlType
== SQL_CHAR
)
1290 *(SQLINTEGER
*)numericAttributePtr
=*(SQLINTEGER
*)numericAttributePtr
-1;
1293 case SQL_DESC_PRECISION
:
1294 case SQL_COLUMN_PRECISION
:
1295 /*if(numericAttributePtr != NULL) // CSQL TODO
1296 *(SQLINTEGER *)numericAttributePtr=(SQLSMALLINT) rsMetaData->getPrecision( columnNumber-1 ); */
1298 case SQL_DESC_SCALE
:
1299 case SQL_COLUMN_SCALE
:
1300 /*if(numericAttributePtr != NULL) // CSQL TODO
1301 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->getScale( columnNumber-1 );*/
1303 case SQL_DESC_NULLABLE
:
1304 case SQL_COLUMN_NULLABLE
:
1305 /*if(numericAttributePtr != NULL) // CSQL TODO
1306 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1308 case SQL_DESC_UNSIGNED
:
1309 if(numericAttributePtr
!= NULL
)
1311 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1312 if((sqlType
!= SQL_TIME
) && (sqlType
!= SQL_DATE
) && (sqlType
!= SQL_TIMESTAMP
)
1313 && (sqlType
!= SQL_CHAR
) && (sqlType
!= SQL_VARCHAR
) && (sqlType
!= SQL_BINARY
)
1314 && (sqlType
!= SQL_VARBINARY
) && (sqlType
!= SQL_BIT
))
1315 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1317 *(SQLINTEGER
*)numericAttributePtr
=SQL_TRUE
;
1320 case SQL_DESC_FIXED_PREC_SCALE
:
1321 if(numericAttributePtr
!= NULL
)
1322 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1324 case SQL_DESC_TYPE_NAME
:
1325 if(characterAttributePtr
!= NULL
)
1327 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1328 strncpy((char*)characterAttributePtr
,(char *)(getSQLTypeName(sqlType
)),bufferLength
);
1329 if(stringLengthPtr
!= NULL
)
1330 *stringLengthPtr
=(int)strlen((char *)getSQLTypeName(sqlType
));
1333 case SQL_DESC_UPDATABLE
:
1334 if(numericAttributePtr
!= NULL
)
1335 *(SQLINTEGER
*)numericAttributePtr
=SQL_ATTR_READWRITE_UNKNOWN
;
1337 case SQL_DESC_AUTO_UNIQUE_VALUE
:
1338 if(numericAttributePtr
!= NULL
)
1339 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1341 case SQL_DESC_CASE_SENSITIVE
:
1342 if(numericAttributePtr
!= NULL
)
1344 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1345 if((sqlType
!= SQL_CHAR
) && (sqlType
!= SQL_VARCHAR
))
1346 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1348 *(SQLINTEGER
*)numericAttributePtr
=SQL_TRUE
;
1351 case SQL_DESC_SEARCHABLE
:
1352 if(numericAttributePtr
!= NULL
)
1354 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1355 if((sqlType
!= SQL_CHAR
) && (sqlType
!= SQL_VARCHAR
))
1356 *(SQLINTEGER
*)numericAttributePtr
=SQL_PRED_BASIC
;
1358 *(SQLINTEGER
*)numericAttributePtr
=SQL_PRED_SEARCHABLE
;
1364 if(stringLengthPtr
!= NULL
)
1366 if(*stringLengthPtr
> bufferLength
)
1368 err_
.set( ERROR_DATATRUNC
);
1369 return( SQL_SUCCESS_WITH_INFO
);
1372 return( SQL_SUCCESS
);
1375 SQLRETURN
SQLNumParams(
1376 SQLHSTMT StatementHandle
,
1377 SQLSMALLINT
* ParameterCountPtr
)
1380 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1381 return( SQL_INVALID_HANDLE
);
1383 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLNumParams(ParameterCountPtr
) );
1386 SQLRETURN
CSqlOdbcStmt::SQLNumParams(
1387 SQLSMALLINT
* ParameterCount
)
1389 // Start with NO_ERR
1393 if( chkStateForSQLNumParams() != SQL_SUCCESS
)
1394 return( SQL_ERROR
);
1395 if(ParameterCount
== NULL
)
1397 *ParameterCount
=fsqlStmt_
->noOfParamFields();
1402 SQLRETURN
SQLDescribeParam(
1403 SQLHSTMT StatementHandle
,
1404 SQLUSMALLINT ParameterNumber
,
1405 SQLSMALLINT
* DataTypePtr
,
1406 SQLUINTEGER
* ParameterSizePtr
,
1407 SQLSMALLINT
* DecimalDigitsPtr
,
1408 SQLSMALLINT
* NullablePtr
)
1411 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1412 return( SQL_INVALID_HANDLE
);
1414 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLDescribeParam(ParameterNumber
,DataTypePtr
,
1415 ParameterSizePtr
,DecimalDigitsPtr
,NullablePtr
) );
1417 SQLRETURN
CSqlOdbcStmt::SQLDescribeParam(
1418 SQLUSMALLINT paramNumber
,
1419 SQLSMALLINT
* dataType
,
1420 SQLUINTEGER
* paramSize
,
1421 SQLSMALLINT
* decimalDigits
,
1422 SQLSMALLINT
* isNullable
)
1425 // Start with NO_ERR
1429 if( chkStateForSQLDescribeParam() != SQL_SUCCESS
)
1430 return( SQL_ERROR
);
1432 if( paramNumber
< 1 )
1434 err_
.set( ERROR_PARAMNUM
);
1435 return( SQL_ERROR
);
1438 //CSqlOdbcError::printDbg("proxy:stmt:getMetaData");
1439 //CSqlParamMetaData *paramMetaData = fsqlStmt_->getParamMetaData();
1440 if(paramNumber
> fsqlStmt_
->noOfParamFields())
1442 err_
.set( ERROR_PARAMNUM
);
1443 return( SQL_ERROR
);
1446 FieldInfo
*finfo
= new FieldInfo();
1447 if( fsqlStmt_
->getParamFldInfo( paramNumber
-1, finfo
) != OK
) return( SQL_ERROR
);
1448 if(dataType
!= NULL
)
1449 *dataType
= (SQLSMALLINT
) getSQLType(finfo
->type
);
1450 if(paramSize
!= NULL
)
1452 *paramSize
= (SQLUINTEGER
) finfo
->length
;
1453 SQLSMALLINT sqlType
=getSQLType(finfo
->type
);
1454 if(sqlType
== SQL_CHAR
)
1455 *paramSize
= *paramSize
-1;
1457 /*if(decimalDigits != NULL) // CSQL TODO
1458 *decimalDigits = (SQLSMALLINT) paramMetaData->getPrecision( paramNumber-1 );
1459 if(isNullable != NULL)
1460 *isNullable = paramMetaData->isNullable( paramNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1461 return( SQL_SUCCESS
);
1464 // Resets the Stmt to initial state. As if newly allocated.
1465 void CSqlOdbcStmt::resetStmt( void ) // TO DO
1467 SQLFreeStmt( SQL_CLOSE
);
1468 SQLFreeStmt( SQL_UNBIND
);
1469 SQLFreeStmt( SQL_RESET_PARAMS
);
1470 if (fsqlStmt_
) { fsqlStmt_
->free(); delete fsqlStmt_
; fsqlStmt_
= NULL
; }
1471 isPrepared_
= false;