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 ),
21 //fetchMode_(SQL_FETCH_SINGLE_TUPLE)
23 cursorName_
[0] = '\0';
26 SQLRETURN
SQLAllocStmt(
27 SQLHDBC ConnectionHandle
,
28 SQLHSTMT
*StatementHandle
)
30 return( CSqlOdbcStmt::SQLAllocHandle( ConnectionHandle
, StatementHandle
) );
33 SQLRETURN
CSqlOdbcStmt::SQLAllocHandle(
34 SQLHANDLE inputHandle
, // IN
35 SQLHANDLE
*outputHandle
) // OUT
37 CSqlOdbcDbc
*inputDbc
= (CSqlOdbcDbc
*) inputHandle
;
40 if( isValidHandle( inputDbc
, SQL_HANDLE_DBC
) != SQL_SUCCESS
)
41 return( SQL_INVALID_HANDLE
);
44 if( inputDbc
->state_
< C4
)
46 globalError
.set( ERROR_CONNOTOPEN
);
47 globalError
.printStr( SQL_OV_ODBC3
);
51 // Allocate Statement object.
52 *outputHandle
= (SQLHANDLE
*) new CSqlOdbcStmt
;
53 if( *outputHandle
== NULL
)
55 globalError
.set( ERROR_MEMALLOC
);
56 globalError
.printStr( SQL_OV_ODBC3
);
60 // Initialize relation b/w Stmt and Dbc
61 inputDbc
->stmtList_
.insert( inputDbc
->stmtList_
.begin(), (CSqlOdbcStmt
*) *outputHandle
);
62 if( inputDbc
->state_
<= C4
)
63 inputDbc
->state_
= C5
;
64 ((CSqlOdbcStmt
*) *outputHandle
)->parentDbc_
= inputDbc
;
65 //CSqlOdbcError::printDbg("proxy:stmt:setConnection");
66 //((CSqlOdbcStmt*) *outputHandle)->fsqlStmt_->setConnection( inputDbc->fsqlConn_ );
68 return( SQL_SUCCESS
);
71 SQLRETURN
CSqlOdbcStmt::SQLFreeHandle(
72 SQLHANDLE inputHandle
) // IN
74 CSqlOdbcStmt
*inputStmt
= (CSqlOdbcStmt
*) inputHandle
;
77 if( isValidHandle( inputStmt
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
78 return( SQL_INVALID_HANDLE
);
81 if( inputStmt
->chkStateForSQLFreeHandle() != SQL_SUCCESS
)
85 inputStmt
->resetStmt();
87 // Remove Stmt from Parent Dbc.
88 std::vector
<CSqlOdbcStmt
*>::iterator iter
;
89 iter
= inputStmt
->parentDbc_
->stmtList_
.begin();
90 while( iter
!= inputStmt
->parentDbc_
->stmtList_
.end() )
92 if( *iter
== inputStmt
)
94 inputStmt
->parentDbc_
->stmtList_
.erase( iter
);
100 // Set Dbc state_ = no statement.
101 if( inputStmt
->parentDbc_
->stmtList_
.size() == 0 )
102 inputStmt
->parentDbc_
->state_
= C4
;
104 inputStmt
->handleType_
= -1; // Make object invalid.
105 delete inputStmt
; // Delete Stmt.
107 return( SQL_SUCCESS
);
110 SQLRETURN
SQLFreeStmt(
111 SQLHSTMT StatementHandle
, // IN
112 SQLUSMALLINT Option
) // IN
115 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
116 return( SQL_INVALID_HANDLE
);
119 if( Option
== SQL_DROP
)
120 return( CSqlOdbcStmt::SQLFreeHandle( StatementHandle
) );
122 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLFreeStmt( Option
) );
125 SQLRETURN
CSqlOdbcStmt::SQLFreeStmt(
132 if( chkStateForSQLFreeStmt() != SQL_SUCCESS
)
134 if (!fsqlStmt_
) return (SQL_SUCCESS
);
137 case SQL_CLOSE
: // // Free resultset
138 // if( fsqlStmt_->isSelect() == true ) // CSQL
140 // //CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
141 // CSqlResultSet *resultSet_ = fsqlStmt_->getResultSet(); // CSQL
142 // if( resultSet_ && resultSet_->isOpen() == true )
144 // resultSet_->close();
151 if( fsqlStmt_
->isSelect() == true ) // CSQL
152 state_
= S3
; // With Cursor
154 state_
= S2
; // Without Cursor
162 fsqlStmt_
->free(); // CSQL
168 case SQL_UNBIND
: ard_
.freeAllDesc();
172 case SQL_RESET_PARAMS
: apd_
.freeAllDesc();
174 //isParamBound_ = false;
177 default: err_
.set( ERROR_OPTRANGE
);
180 return( SQL_SUCCESS
);
183 SQLRETURN
SQLBindCol(
184 SQLHSTMT StatementHandle
,
185 SQLUSMALLINT ColumnNumber
,
186 SQLSMALLINT TargetType
,
187 SQLPOINTER TargetValue
,
188 SQLINTEGER BufferLength
,
189 SQLINTEGER
*StrLen_or_Ind
)
192 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
193 return( SQL_INVALID_HANDLE
);
195 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLBindCol( ColumnNumber
,
196 TargetType
, TargetValue
, BufferLength
, StrLen_or_Ind
) );
199 SQLRETURN
CSqlOdbcStmt::SQLBindCol(
200 SQLUSMALLINT columnNumber
,
201 SQLSMALLINT targetType
,
202 SQLPOINTER targetValue
,
203 SQLINTEGER bufferLength
,
206 CSqlOdbcDesc
*bindDesc
= 0;
207 CSqlOdbcDesc
*inputDesc
= 0;
208 SQLRETURN found
= SQL_ERROR
;
214 if( chkStateForSQLBindCol() != SQL_SUCCESS
)
217 // Invalid Buffer Length.
220 // switch is in order to support more types.
222 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
224 err_
.set( ERROR_BUFLEN
);
229 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
231 err_
.set( ERROR_BUFLEN
);
237 // Invalid Column Number
238 if( columnNumber
< 1 )
240 err_
.set( ERROR_COLNUM
);
244 // Get the Descriptor if already exists
245 found
= ard_
.getDescWithColNum( columnNumber
, &bindDesc
);
248 if( targetValue
== 0 )
250 if( found
!= SQL_SUCCESS
)
252 err_
.set( ERROR_COLNUM
);
255 ard_
.delDesc( bindDesc
); // UNBIND
257 return( SQL_SUCCESS
);
260 // Validate target Type, Value and Column no.
261 if( targetValue
== 0 || isValidCType( targetType
) != SQL_SUCCESS
)
263 err_
.set( ERROR_INVBUFTYPE
);
267 // Add new descriptor
268 if( found
!= SQL_SUCCESS
)
270 bindDesc
= new CSqlOdbcDesc();
271 ard_
.insert( ard_
.begin(), bindDesc
);
274 // Initialize Descriptor.
275 bindDesc
->col_
= columnNumber
;
276 bindDesc
->cType_
= targetType
;
277 bindDesc
->dataPtr_
= targetValue
;
278 bindDesc
->length_
= (SQLUINTEGER
) bufferLength
;
279 bindDesc
->indPtr_
= (SQLPOINTER
) ind
;
281 found
= ird_
.getDescWithColNum( columnNumber
, &inputDesc
);
283 // Add new descriptor
284 if( found
!= SQL_SUCCESS
)
286 inputDesc
= new CSqlOdbcDesc();
287 ird_
.insert(ird_
.begin(),inputDesc
);
290 // Initialize input Descriptor.
291 DataType sourceType
= getCSqlType( targetType
);
292 inputDesc
->col_
= columnNumber
;
293 inputDesc
->cType_
= targetType
;
294 getInputBuffer(&inputDesc
->dataPtr_
,sourceType
,(SQLUINTEGER
) bufferLength
);
295 inputDesc
->length_
= (SQLUINTEGER
) bufferLength
;
296 inputDesc
->indPtr_
= (SQLPOINTER
) ind
;
298 return( SQL_SUCCESS
);
301 SQLRETURN
SQLSetParam(
302 SQLHSTMT StatementHandle
,
303 SQLUSMALLINT ParameterNumber
,
304 SQLSMALLINT ValueType
,
305 SQLSMALLINT ParameterType
,
306 SQLUINTEGER LengthPrecision
,
307 SQLSMALLINT ParameterScale
,
308 SQLPOINTER ParameterValue
,
309 SQLINTEGER
*StrLen_or_Ind
)
311 return( SQLBindParameter( StatementHandle
, ParameterNumber
,
312 SQL_PARAM_INPUT_OUTPUT
, ValueType
, ParameterType
, LengthPrecision
,
313 ParameterScale
, ParameterValue
, 0, StrLen_or_Ind
) );
316 SQLRETURN
SQLBindParam(
317 SQLHSTMT StatementHandle
,
318 SQLUSMALLINT ParameterNumber
,
319 SQLSMALLINT ValueType
,
320 SQLSMALLINT ParameterType
,
321 SQLUINTEGER LengthPrecision
,
322 SQLSMALLINT ParameterScale
,
323 SQLPOINTER ParameterValue
,
324 SQLINTEGER
*StrLen_or_Ind
)
326 return( SQLBindParameter( StatementHandle
, ParameterNumber
,
327 SQL_PARAM_INPUT_OUTPUT
, ValueType
, ParameterType
, LengthPrecision
,
328 ParameterScale
, ParameterValue
, 0, StrLen_or_Ind
) );
331 SQLRETURN
SQLBindParameter(
332 SQLHSTMT StatementHandle
,
333 SQLUSMALLINT ParameterNumber
,
334 SQLSMALLINT InputOutputType
,
335 SQLSMALLINT ValueType
,
336 SQLSMALLINT ParameterType
,
337 SQLUINTEGER LengthPrecision
,
338 SQLSMALLINT ParameterScale
,
339 SQLPOINTER ParameterValue
,
340 SQLINTEGER BufferLength
,
341 SQLINTEGER
*StrLen_or_Ind
)
344 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
345 return( SQL_INVALID_HANDLE
);
347 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLBindParameter( ParameterNumber
,
348 InputOutputType
, ValueType
,
349 ParameterType
, LengthPrecision
,
350 ParameterScale
, ParameterValue
,
351 BufferLength
, StrLen_or_Ind
) );
354 SQLRETURN
CSqlOdbcStmt::SQLBindParameter(
355 SQLUSMALLINT parameterNumber
,
356 SQLSMALLINT inputOutputType
,
357 SQLSMALLINT valueType
,
358 SQLSMALLINT parameterType
,
359 SQLUINTEGER lengthPrecision
,
360 SQLSMALLINT parameterScale
,
361 SQLPOINTER parameterValue
,
362 SQLINTEGER bufferLength
,
365 CSqlOdbcDesc
*bindDesc
= 0;
366 CSqlOdbcDesc
*inputDesc
=0;
373 if( chkStateForSQLBindParameter() != SQL_SUCCESS
)
376 // Invalid Buffer Length.
379 // switch is in order to support more types.
381 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
383 err_
.set( ERROR_BUFLEN
);
388 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
390 err_
.set( ERROR_BUFLEN
);
396 // Validate parameters
397 switch( inputOutputType
)
399 case SQL_PARAM_INPUT
:
400 case SQL_PARAM_OUTPUT
:
401 case SQL_PARAM_INPUT_OUTPUT
: break;
402 default: err_
.set( ERROR_INV_PARAMTYPE
);
405 if( isValidCType( valueType
) != SQL_SUCCESS
||
406 isValidSQLType( parameterType
) != SQL_SUCCESS
)
408 err_
.set( ERROR_INVBUFTYPE
);
411 if( parameterNumber
< 1 )
413 err_
.set( ERROR_COLNUM
);
417 // Get the Descriptor if already exists
418 found
= apd_
.getDescWithColNum( parameterNumber
, &bindDesc
);
419 if( found
!= SQL_SUCCESS
)
421 bindDesc
= new CSqlOdbcDesc();
422 apd_
.insert( apd_
.end(), bindDesc
);
423 // Initialize Descriptor.
424 bindDesc
->col_
= parameterNumber
;
425 bindDesc
->paramType_
= inputOutputType
;
426 bindDesc
->cType_
= valueType
;
427 bindDesc
->sqlType_
= parameterType
;
428 bindDesc
->dataPtr_
= parameterValue
;
429 bindDesc
->length_
= (SQLUINTEGER
) bufferLength
;
430 bindDesc
->precision_
=(short) lengthPrecision
;
431 bindDesc
->scale_
= parameterScale
;
432 bindDesc
->indPtr_
= (SQLPOINTER
) ind
;
434 found
= ipd_
.getDescWithColNum (parameterNumber
, &inputDesc
);
435 if( found
!= SQL_SUCCESS
)
437 inputDesc
= new CSqlOdbcDesc();
438 ipd_
.insert(ipd_
.end(),inputDesc
);
439 //Initialize inputDescriptor
440 DataType destType
=getCSqlType(valueType
);
441 inputDesc
->col_
= parameterNumber
;
442 inputDesc
->paramType_
= inputOutputType
;
443 inputDesc
->cType_
= valueType
;
444 inputDesc
->sqlType_
= parameterType
;
445 inputDesc
->dataPtr_
= NULL
;
446 //getInputBuffer(&inputDesc->dataPtr_,destType,(SQLUINTEGER)bufferLength);
447 inputDesc
->length_
= (SQLUINTEGER
) bufferLength
;
448 inputDesc
->precision_
= (short)lengthPrecision
;
449 inputDesc
->scale_
= parameterScale
;
450 inputDesc
->indPtr_
= (SQLPOINTER
) ind
;
452 //isParamBound_ = false;
453 return( SQL_SUCCESS
);
456 SQLRETURN
SQLPrepare(
457 SQLHSTMT StatementHandle
, // IN
458 SQLCHAR
*StatementText
, // IN
459 SQLINTEGER TextLength
) // IN
462 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
463 return( SQL_INVALID_HANDLE
);
466 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLPrepare( StatementText
, TextLength
) );
469 SQLRETURN
CSqlOdbcStmt::SQLPrepare(
470 SQLCHAR
*statementText
, // IN
471 SQLINTEGER textLength
) // IN
477 if( chkStateForSQLPrepare() != SQL_SUCCESS
)
480 // Invalid Buffer Length.
481 if( textLength
< 0 && textLength
!= SQL_NTS
)
483 err_
.set( ERROR_BUFLEN
);
487 // If Stmt is already prepared.
492 if (parentDbc_
->mode_
==1)
493 fsqlStmt_
= SqlFactory::createStatement(CSql
);
494 else if (parentDbc_
->mode_
==2)
495 fsqlStmt_
= SqlFactory::createStatement(CSqlGateway
);
496 else if (parentDbc_
->mode_
==3)
497 fsqlStmt_
= SqlFactory::createStatement(CSqlAdapter
);
498 fsqlStmt_
->setConnection( parentDbc_
->fsqlConn_
);
501 //CSqlOdbcError::printDbg("proxy:stmt:prepare");
503 if( (rv
=fsqlStmt_
->prepare( (char*) statementText
))!= OK
) // CSQL
506 err_
.set(ERROR_GENERAL
);
509 case csqlSqlErrSchNotFound: err_.set( ERROR_SCHNOTFOUND); break;
510 case csqlSqlErrTblNotFound: err_.set( ERROR_TBLNOTFOUND); break;
511 case csqlSqlErrFldNotFound: err_.set( ERROR_NO_COLEXISTS); break;
512 case csqlSqlErrIndexNotFound: err_.set( ERROR_NO_IDXEXISTS); break;
513 case csqlSqlErrViewNotFound: err_.set( ERROR_TBLNOTFOUND); break;
514 case csqlSqlErrTblExists: err_.set( ERROR_TBLEXISTS); break;
515 case csqlSqlErrFldExists: err_.set( ERROR_COLEXISTS); break;
516 case csqlSqlErrIndexExists: err_.set( ERROR_IDXEXISTS); break;
517 case csqlSqlErrViewExists: err_.set( ERROR_TBLEXISTS); break;
518 case csqlSqlErrTooManyVals:err_.set(ERROR_MANY_VALS);break;
519 case csqlSqlErrTooFewVals:err_.set(ERROR_FEW_VALS);break;
520 case csqlSqlErrSqlSyntaxError:err_.set(ERROR_SQL_SYNTAX);break;
521 case csqlSqlErrIncompatibleType:err_.set(ERROR_TYPE_INCMP);break;
522 case csqlSqlErrInvalidFormat:err_.set(ERROR_DATA_FORMAT);break;
523 case csqlSqlErrDuplicateFld:err_.set(ERROR_DUP_COL);break;
524 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
529 if( fsqlStmt_
->isSelect() != true ) // CSQL
530 state_
= S2
; // With cursor
532 state_
= S3
; // Without cursor
534 //parentDbc_->state_ = C6;
536 return( SQL_SUCCESS
);
539 SQLRETURN
SQLExecute(SQLHSTMT StatementHandle
) // IN
542 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
543 return( SQL_INVALID_HANDLE
);
545 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLExecute() );
548 SQLRETURN
CSqlOdbcStmt::SQLExecute() // TODO
554 if( chkStateForSQLExecute() != SQL_SUCCESS
)
557 if( fsqlStmt_
->noOfParamFields() > 0 )
560 // Iterate through all apd_;
561 CSqlOdbcDesc
*appParamDesc
;
562 CSqlOdbcDescList::iterator apdIter
;
563 apdIter
= apd_
.begin();
564 CSqlOdbcDesc
*csqlParamDesc
;
565 CSqlOdbcDescList::iterator ipdIter
;
566 ipdIter
= ipd_
.begin();
568 //Get the source and the destination type
569 DataType sourceType
= typeUnknown
,destType
= typeUnknown
;
570 int paramNum
=1,sourceLength
=-1,destLength
=-1;
573 while( (apdIter
!= apd_
.end()) || (ipdIter
!= ipd_
.end()) )
575 appParamDesc
=*apdIter
;
576 csqlParamDesc
=*ipdIter
;
577 if((paramNum
) <= fsqlStmt_
->noOfParamFields())
579 FieldInfo
*finfo
= new FieldInfo();
580 if( fsqlStmt_
->getParamFldInfo(paramNum
, finfo
) != OK
) return( SQL_ERROR
);
581 sourceType
=getCSqlType(appParamDesc
->cType_
);
582 destType
=finfo
->type
;
583 sourceLength
=(int)appParamDesc
->length_
;
584 destLength
=finfo
->length
;
586 if(sourceType
!= typeUnknown
&& destType
!= typeUnknown
)
588 //Check if NULL is inserted
589 if((appParamDesc
->indPtr_
!= NULL
) && (*(SQLINTEGER
*)appParamDesc
->indPtr_
) == SQL_NULL_DATA
)
592 //finfo->isNull = true; CSQL TODO - need to understand how to set null
596 //Only if both types are not the same, then we need to copy it onto intermediate buffer
598 if( (sourceType
== typeString
|| sourceType
== typeBinary
) && (sourceLength
<= 0))
600 if((appParamDesc
->indPtr_
!= NULL
) && *(SQLINTEGER
*)appParamDesc
->indPtr_
> 0)
601 sourceLength
=(int)(*(SQLINTEGER
*)appParamDesc
->indPtr_
);
602 else if (appParamDesc
->precision_
> 0)
603 sourceLength
=appParamDesc
->precision_
;
606 err_
.set( ERROR_BUFLEN
);
610 if(destType
== typeString
) //|| destType == typeVarString)
612 //fsqlStmt_->allocParam(paramNum,sourceLength); // CSQL TODO
613 destLength
=sourceLength
;
615 if(sourceType
== destType
)
616 //|| (sourceType == typeString && destType == typeVarString)
617 //|| (sourceType == typeBinary && destType == typeVarBinary))
619 copyFromOdbc(fsqlStmt_
, paramNum
, destLength
, appParamDesc
->dataPtr_
, sourceLength
,destType
); // CSQL TODO
622 getInputBuffer(&csqlParamDesc
->dataPtr_
,sourceType
,sourceLength
);
623 copyFromOdbc(fsqlStmt_
, paramNum
, destLength
, appParamDesc
->dataPtr_
, sourceLength
, sourceType
);
624 //convert(sourceType,csqlParamDesc->dataPtr_,destType, fsqlStmt_->getParamPtr( paramNum),sourceLength,destLength); // CSQL TODO
630 err_
.set(ERROR_GENERAL
);
643 DbRetVal rv
= fsqlStmt_
->execute( rowsAffected
);
644 if( rowsAffected
< 0 )
646 if( isPrepared_
) state_
= S2
; else resetStmt();
647 err_
.set( ERROR_GENERAL
);
650 case csqlSqlErrOverflow:err_.set(ERROR_OVERFLOW);break;
651 case csqlSqlErrUnderflow:err_.set(ERROR_UNDERFLOW);break;
652 case csqlSqlErrTooManyTpl:err_.set(ERROR_MANY_TUP);break;
653 case csqlSqlErrProjCnt:err_.set(ERROR_NUM_PROJ);break;
654 case csqlSqlErrStorageAttr:err_.set(ERROR_STORAGE_ATTR);break;
655 case csqlSqlErrFldCntMismatch:err_.set(ERROR_FLDCNT_MISMATCH);break;
656 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
657 case csqlSqlErrNoMatchKeyFound:err_.set(ERROR_MATCHKEY_NOTFOUND);break;
659 err_.set( ERROR_GENERAL );break;
665 if( fsqlStmt_
->isSelect() == true )
672 rowsAffected_
= rowsAffected
;
676 // Set Dbc State to Transaction Mode.
677 parentDbc_
->state_
= C6
;
680 if( parentDbc_
->autoCommit_
== SQL_AUTOCOMMIT_ON
)
681 parentDbc_
->SQLEndTran( SQL_COMMIT
);
683 return( SQL_SUCCESS
);
686 SQLRETURN
SQLExecDirect(
687 SQLHSTMT StatementHandle
,
688 SQLCHAR
*StatementText
,
689 SQLINTEGER TextLength
)
692 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
693 return( SQL_INVALID_HANDLE
);
695 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLExecDirect( StatementText
, TextLength
) );
698 SQLRETURN
CSqlOdbcStmt::SQLExecDirect(
699 SQLCHAR
*statementText
,
700 SQLINTEGER textLength
)
705 if( chkStateForSQLExecDirect() != SQL_SUCCESS
)
708 // SQLExecDirect = SQLPrepare + SQLExecute.
709 if( SQLPrepare( statementText
, textLength
) != SQL_SUCCESS
)
713 isPrepared_
= false; // Set Stmt as non-prepared stmt.
715 if( ret
!= SQL_SUCCESS
)
718 return( SQL_SUCCESS
);
721 SQLRETURN
SQLSetStmtOption(
722 SQLHSTMT StatementHandle
,
726 return (SQLSetStmtAttr(StatementHandle
, Option
, (SQLPOINTER
) Value
, 0));
729 SQLRETURN SQL_API
SQLSetStmtAttr(SQLHSTMT StatementHandle
,
730 SQLINTEGER Attribute
, SQLPOINTER Value
,
731 SQLINTEGER StringLength
)
733 return (((CSqlOdbcStmt
*)StatementHandle
)->SQLSetStmtAttr(Attribute
, Value
,StringLength
));
736 SQLRETURN
CSqlOdbcStmt::SQLSetStmtAttr(
737 SQLINTEGER Attribute
,
739 SQLINTEGER stringLength
)
741 CSqlOdbcError::printDbg("proxy:stmt:SQLSetStmtAttr");
745 //Values: SQL_FETCH_SINGLE_TUPLE or SQL_FETCH_MULTIPLE_TUPLES
746 //Default is SQL_FETCH_SINGLE_TUPLE.
747 //In SQL_FETCH_SINGLE_TUPLE mode, only a single tuple
748 //is sent from server to client in a single packet whatever be
749 //the packet size. If a tuple size is 50 and network packet size
750 //is 500, the remaining 450 bytes can also be used to send more
751 //in a single packet so that in the next SQLFetch call one network
752 //packet transfer overhead is reduced.
755 //state_ > S5 means Fetch has already started on this statement.
756 fetchMode_ = (SQLINTEGER)Value;
758 printf("ODBC:Error in setting fetch mode, can't set after fetch is started.\n");
761 printf("ODBC: Error, Stmt Option %d is not supported.\n", Attribute);
763 return (SQL_SUCCESS
);
766 SQLRETURN
SQLFetch(SQLHSTMT StatementHandle
)
769 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
770 return( SQL_INVALID_HANDLE
);
772 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLFetch() );
775 SQLRETURN
CSqlOdbcStmt::SQLFetch()
781 if( chkStateForSQLFetch() != SQL_SUCCESS
)
785 tuple
= fsqlStmt_
->next();
787 if( ! tuple
) // IF Row not found.
791 return( SQL_NO_DATA_FOUND
);
793 /*else if( rowsAffected != SQL_SUCCESS ) // IF Error
796 err_.set( ERROR_GENERAL );
799 else // IF Row found.
803 // Iterate through all ard_;
804 CSqlOdbcDesc
*appColDesc
;
805 CSqlOdbcDescList::iterator ardIter
;
806 ardIter
= ard_
.begin();
807 //Get the input parameter data
808 CSqlOdbcDesc
*csqlColDesc
;
809 CSqlOdbcDescList::iterator irdIter
;
810 irdIter
= ird_
.begin();
812 DataType sourceType
= typeUnknown
,destType
= typeUnknown
;
813 int colNum
=-1,sourceLength
=-1,destLength
=-1;
815 void* sourceData
= NULL
;
816 FieldInfo
*info
= new FieldInfo();
817 while( (ardIter
!= ard_
.end()) || (irdIter
!= ird_
.end()) )
819 appColDesc
= *ardIter
;
820 csqlColDesc
= *irdIter
;
822 colNum
= appColDesc
->col_
- 1;
823 fsqlStmt_
->getProjFldInfo(colNum
, info
);
824 sourceType
= info
->type
;
825 destType
= getCSqlType(appColDesc
->cType_
);
826 sourceLength
= info
->length
;
827 destLength
= (int)appColDesc
->length_
;
829 if( sourceType
!= typeUnknown
&& destType
!= typeUnknown
)
831 sourceData
= fsqlStmt_
->getFieldValuePtr( colNum
);
832 if(sourceData
== NULL
)
834 if (appColDesc
->indPtr_
!= NULL
)
835 *((SQLINTEGER
*)(appColDesc
->indPtr_
))=SQL_NULL_DATA
;
839 /*if( sourceType == csqlSqlTvarBinary)
840 sourceLength=resultSet_->getDataLength(colNum); */
841 if (sourceType
== typeString
) // CSQL TODO - handle varchar also
843 sourceLength
=(int)(strlen((char *) sourceData
));
844 if(appColDesc
->indPtr_
!= NULL
)
845 *((SQLINTEGER
*)(appColDesc
->indPtr_
))=copyToOdbc(appColDesc
->dataPtr_
,destLength
,
846 sourceData
,sourceLength
, sourceType
);
848 copyToOdbc(appColDesc
->dataPtr_
,destLength
,sourceData
,
849 sourceLength
, sourceType
);
853 //convert(sourceType,sourceData,destType, csqlColDesc->dataPtr_,sourceLength,destLength);
854 if(appColDesc
->indPtr_
!= NULL
)
855 *((SQLINTEGER
*)(appColDesc
->indPtr_
))=
856 copyToOdbc(appColDesc
->dataPtr_
,destLength
, sourceData
, sourceLength
, sourceType
);
858 copyToOdbc(appColDesc
->dataPtr_
,destLength
, sourceData
, sourceLength
, sourceType
);
861 // CSQL TODO - handle varstring, binary, varbinary
862 if( sourceType
== typeString
&& sourceLength
> destLength
)
863 err_
.set( ERROR_DATATRUNC
);
871 if(err_
.csqlErrCode
== ERROR_DATATRUNC
)
872 return (SQL_SUCCESS_WITH_INFO
);
874 return( SQL_SUCCESS
);
877 SQLRETURN
SQLCloseCursor(SQLHSTMT StatementHandle
)
880 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
881 return( SQL_INVALID_HANDLE
);
883 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLCloseCursor() );
886 SQLRETURN
CSqlOdbcStmt::SQLCloseCursor()
892 if( chkStateForSQLCloseCursor() != SQL_SUCCESS
)
898 return( SQL_SUCCESS
);
901 SQLRETURN
SQLSetCursorName(
902 SQLHSTMT StatementHandle
,
904 SQLSMALLINT NameLength
)
907 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
908 return( SQL_INVALID_HANDLE
);
910 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLSetCursorName( CursorName
, NameLength
) );
913 SQLRETURN
CSqlOdbcStmt::SQLSetCursorName(
915 SQLSMALLINT nameLength
)
921 if( chkStateForSQLSetCursorName() != SQL_SUCCESS
)
924 // Invalid Stmt Length.
925 if( nameLength
< 0 && nameLength
!= SQL_NTS
)
927 err_
.set( ERROR_INVARGVAL
);
931 // Validate Parameters
932 if( cursorName
== 0 || cursorName
[0] == '\0' || strlen( (char*) cursorName
) > SQL_MAX_CURSOR_NAME_LEN
||
933 nameLength
> SQL_MAX_CURSOR_NAME_LEN
)
935 err_
.set( ERROR_CURNAME
);
939 // Check for duplicate Name
940 std::vector
<CSqlOdbcStmt
*>::iterator iter
;
941 iter
= parentDbc_
->stmtList_
.begin();
942 while( iter
!= parentDbc_
->stmtList_
.end() )
946 if( strcmp( (char*) cursorName
, (char*) (*iter
)->cursorName_
) == 0 )
948 err_
.set( ERROR_DUP_CURNAME
);
956 strcpy( (char*) cursorName_
, (char*) cursorName
);
958 return( SQL_SUCCESS
);
961 SQLRETURN
SQLGetCursorName(
962 SQLHSTMT StatementHandle
,
964 SQLSMALLINT BufferLength
,
965 SQLSMALLINT
*NameLength
)
968 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
969 return( SQL_INVALID_HANDLE
);
971 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLGetCursorName( CursorName
, BufferLength
, NameLength
) );
973 SQLRETURN
CSqlOdbcStmt::SQLGetCursorName(
975 SQLSMALLINT bufferLength
,
976 SQLSMALLINT
*nameLength
)
979 if( chkStateForSQLGetCursorName() != SQL_SUCCESS
)
982 if( cursorName_
[0] == '\0' )
984 err_
.set( ERROR_NOCURNAME
);
989 *nameLength
= (short)strlen( (char*) cursorName_
);
990 if( *nameLength
> bufferLength
) *nameLength
= bufferLength
;
991 strncpy( (char*) cursorName
, (char*) cursorName_
, *nameLength
);
992 cursorName
[ *nameLength
] = '\0';
995 if( bufferLength
< strlen( (char*) cursorName_
) )
997 err_
.set( ERROR_DATATRUNC
);
998 return( SQL_SUCCESS_WITH_INFO
);
1001 return( SQL_SUCCESS
);
1004 SQLRETURN
SQLNumResultCols(
1005 SQLHSTMT StatementHandle
, // IN
1006 SQLSMALLINT
*ColumnCount
) // OUT
1009 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1010 return( SQL_INVALID_HANDLE
);
1012 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLNumResultCols( ColumnCount
) );
1015 SQLRETURN
CSqlOdbcStmt::SQLNumResultCols(
1016 SQLSMALLINT
*columnCount
) // OUT
1018 // Start with NO_ERR
1022 if( chkStateForSQLNumResultCols() != SQL_SUCCESS
)
1023 return( SQL_ERROR
);
1026 if( fsqlStmt_
->isSelect() == false )
1029 return (SQL_SUCCESS
);
1033 SQLSMALLINT count
= fsqlStmt_
->noOfProjFields();
1034 if( count
< 1 ) // Assume atleast one column is projected
1035 return( SQL_ERROR
);
1037 // Fill Column Count
1038 *columnCount
= count
;
1040 return( SQL_SUCCESS
);
1043 SQLRETURN SQL_API
SQLRowCount(
1044 SQLHSTMT StatementHandle
, // IN
1045 SQLINTEGER
*RowCount
) // OUT
1048 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1049 return( SQL_INVALID_HANDLE
);
1051 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLRowCount( RowCount
) );
1054 SQLRETURN
CSqlOdbcStmt::SQLRowCount(
1055 SQLINTEGER
*rowCount
) // OUT
1057 // Start with NO_ERR
1061 if( chkStateForSQLRowCount() != SQL_SUCCESS
)
1062 return( SQL_ERROR
);
1064 if(rowCount
== NULL
)
1067 if( state_
== S4
) // For INSERT/DELETE/UPDATE
1068 *rowCount
= (SQLINTEGER
) rowsAffected_
;
1069 else if( state_
== S5
) // For SELECT before SQLFetch()
1071 *rowCount
= (SQLINTEGER
) 0;
1072 // CSQL TODO - Think if you really want to do this!!!
1074 /*CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
1075 CSqlResultSet *resultSet_ = fsqlStmt_.getResultSet();
1076 if( resultSet_->next() != csqlSqlErrNoTuple )
1077 *rowCount = (SQLINTEGER) 1;
1079 resultSet_->close();
1080 resultSet_->open(); */
1082 else if( state_
== S6
) // For SELECT after SQLFetch();
1083 *rowCount
= (SQLINTEGER
) rowsAffected_
;
1085 return( SQL_SUCCESS
);
1088 SQLRETURN
SQLDescribeCol(
1089 SQLHSTMT StatementHandle
,
1090 SQLUSMALLINT ColumnNumber
,
1091 SQLCHAR
*ColumnName
,
1092 SQLSMALLINT BufferLength
,
1093 SQLSMALLINT
*NameLength
,
1094 SQLSMALLINT
*DataType
,
1095 SQLUINTEGER
*ColumnSize
,
1096 SQLSMALLINT
*DecimalDigits
,
1097 SQLSMALLINT
*Nullable
)
1100 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1101 return( SQL_INVALID_HANDLE
);
1103 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLDescribeCol( ColumnNumber
, ColumnName
, BufferLength
,
1104 NameLength
, DataType
, ColumnSize
, DecimalDigits
, Nullable
) );
1107 SQLRETURN
CSqlOdbcStmt::SQLDescribeCol(
1108 SQLUSMALLINT columnNumber
,
1109 SQLCHAR
*columnName
,
1110 SQLSMALLINT bufferLength
,
1111 SQLSMALLINT
*nameLength
,
1112 SQLSMALLINT
*dataType
,
1113 SQLUINTEGER
*columnSize
,
1114 SQLSMALLINT
*decimalDigits
,
1115 SQLSMALLINT
*nullable
)
1123 // Start with NO_ERR
1127 if( chkStateForSQLDescribeCol() != SQL_SUCCESS
)
1128 return( SQL_ERROR
);
1130 if( columnNumber
< 1 )
1132 err_
.set( ERROR_COLNUM
);
1133 return( SQL_ERROR
);
1137 if( fsqlStmt_
->isSelect() == false )
1138 return( SQL_ERROR
);
1141 if(columnNumber
> fsqlStmt_
->noOfProjFields())
1143 err_
.set( ERROR_COLNUM
);
1144 return( SQL_ERROR
);
1146 if(columnName
== NULL
) {
1147 err_
.set( ERROR_COLNUM
);
1148 return( SQL_ERROR
);
1150 FieldInfo
*info
= new FieldInfo();
1151 fsqlStmt_
->getProjFldInfo(columnNumber
, info
);
1152 strncpy( (char*)columnName
, (char*)info
->fldName
, bufferLength
);
1153 if(nameLength
!= NULL
)
1154 *nameLength
=(short)strlen((const char*)info
->fldName
); // HARDCODED - TO DO, need support for n/w layer & sql layer
1155 if(dataType
!= NULL
)
1156 *dataType
= (SQLSMALLINT
) getSQLType(info
->type
); // Need to convert from SQL<->ODBC - TO DO
1157 if(columnSize
!= NULL
)
1159 *columnSize
= (SQLUINTEGER
) info
->length
;
1160 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1161 if(sqlType
== SQL_CHAR
)
1162 *columnSize
= *columnSize
-1;
1165 /*if(decimalDigits != NULL) // CSQL TODO
1166 *decimalDigits = (SQLSMALLINT) fsqlStmt_->getPrecision( columnNumber-1 );
1167 if(nullable != NULL)
1168 *nullable = rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N; */
1169 if(strlen((char*)info
->fldName
) > bufferLength
)
1171 err_
.set( ERROR_DATATRUNC
);
1172 return( SQL_SUCCESS_WITH_INFO
);
1175 return( SQL_SUCCESS
);
1178 SQLRETURN
SQLColAttributes(
1179 SQLHSTMT StatementHandle
,
1180 SQLUSMALLINT ColumnNumber
,
1181 SQLUSMALLINT FieldIdentifier
,
1182 SQLPOINTER CharacterAttributePtr
,
1183 SQLSMALLINT BufferLength
,
1184 SQLSMALLINT
*StringLengthPtr
,
1185 SQLINTEGER
*NumericAttributePtr
)
1188 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1189 return( SQL_INVALID_HANDLE
);
1191 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLColAttribute(ColumnNumber
,FieldIdentifier
,
1192 CharacterAttributePtr
, BufferLength
, StringLengthPtr
, (SQLPOINTER
)NumericAttributePtr
) );
1195 SQLRETURN
SQLColAttribute(
1196 SQLHSTMT StatementHandle
,
1197 SQLUSMALLINT ColumnNumber
,
1198 SQLUSMALLINT FieldIdentifier
,
1199 SQLPOINTER CharacterAttributePtr
,
1200 SQLSMALLINT BufferLength
,
1201 SQLSMALLINT
* StringLengthPtr
,
1202 SQLPOINTER NumericAttributePtr
)
1205 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1206 return( SQL_INVALID_HANDLE
);
1208 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLColAttribute(ColumnNumber
,FieldIdentifier
,
1209 CharacterAttributePtr
, BufferLength
, StringLengthPtr
, NumericAttributePtr
) );
1212 SQLRETURN
CSqlOdbcStmt::SQLColAttribute(
1213 SQLUSMALLINT columnNumber
,
1214 SQLUSMALLINT fieldIdentifier
,
1215 SQLPOINTER characterAttributePtr
,
1216 SQLSMALLINT bufferLength
,
1217 SQLSMALLINT
* stringLengthPtr
,
1218 SQLPOINTER numericAttributePtr
)
1226 // Start with NO_ERR
1230 if( chkStateForSQLDescribeCol() != SQL_SUCCESS
)
1231 return( SQL_ERROR
);
1233 if( columnNumber
< 1 )
1235 err_
.set( ERROR_COLNUM
);
1236 return( SQL_ERROR
);
1239 if( fsqlStmt_
->isSelect() == false )
1240 return( SQL_ERROR
);
1242 FieldInfo
*info
= new FieldInfo();
1243 fsqlStmt_
->getProjFldInfo(columnNumber
, info
);
1246 if(columnNumber
> fsqlStmt_
->noOfProjFields())
1248 err_
.set( ERROR_COLNUM
);
1249 return( SQL_ERROR
);
1251 switch(fieldIdentifier
)
1254 case SQL_COLUMN_NAME
:
1255 if(characterAttributePtr
!= NULL
)
1257 strncpy( (char*)characterAttributePtr
, (char*)info
->fldName
, bufferLength
);
1258 if(stringLengthPtr
!= NULL
)
1259 *stringLengthPtr
=(short)strlen((char*)info
->fldName
);
1262 case SQL_DESC_COUNT
:
1263 case SQL_COLUMN_COUNT
:
1264 if(numericAttributePtr
!= NULL
)
1265 *(SQLINTEGER
*)numericAttributePtr
=fsqlStmt_
->noOfProjFields();
1268 case SQL_COLUMN_TYPE
:
1269 if(numericAttributePtr
!= NULL
)
1270 *(SQLINTEGER
*)numericAttributePtr
=getSQLType(info
->type
);
1272 case SQL_DESC_LENGTH
:
1273 case SQL_COLUMN_LENGTH
:
1274 if(numericAttributePtr
!= NULL
)
1276 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1277 *(SQLINTEGER
*)numericAttributePtr
=(SQLUINTEGER
) info
->length
;
1278 if(sqlType
== SQL_CHAR
)
1279 *(SQLINTEGER
*)numericAttributePtr
=*(SQLINTEGER
*)numericAttributePtr
-1;
1282 case SQL_DESC_PRECISION
:
1283 case SQL_COLUMN_PRECISION
:
1284 /*if(numericAttributePtr != NULL) // CSQL TODO
1285 *(SQLINTEGER *)numericAttributePtr=(SQLSMALLINT) rsMetaData->getPrecision( columnNumber-1 ); */
1287 case SQL_DESC_SCALE
:
1288 case SQL_COLUMN_SCALE
:
1289 /*if(numericAttributePtr != NULL) // CSQL TODO
1290 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->getScale( columnNumber-1 );*/
1292 case SQL_DESC_NULLABLE
:
1293 case SQL_COLUMN_NULLABLE
:
1294 /*if(numericAttributePtr != NULL) // CSQL TODO
1295 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1297 case SQL_DESC_UNSIGNED
:
1298 if(numericAttributePtr
!= NULL
)
1300 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1301 if((sqlType
!= SQL_TIME
) && (sqlType
!= SQL_DATE
) && (sqlType
!= SQL_TIMESTAMP
)
1302 && (sqlType
!= SQL_CHAR
) && (sqlType
!= SQL_VARCHAR
) && (sqlType
!= SQL_BINARY
)
1303 && (sqlType
!= SQL_VARBINARY
) && (sqlType
!= SQL_BIT
))
1304 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1306 *(SQLINTEGER
*)numericAttributePtr
=SQL_TRUE
;
1309 case SQL_DESC_FIXED_PREC_SCALE
:
1310 if(numericAttributePtr
!= NULL
)
1311 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1313 case SQL_DESC_TYPE_NAME
:
1314 if(characterAttributePtr
!= NULL
)
1316 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1317 strncpy((char*)characterAttributePtr
,(char *)(getSQLTypeName(sqlType
)),bufferLength
);
1318 if(stringLengthPtr
!= NULL
)
1319 *stringLengthPtr
=(int)strlen((char *)getSQLTypeName(sqlType
));
1322 case SQL_DESC_UPDATABLE
:
1323 if(numericAttributePtr
!= NULL
)
1324 *(SQLINTEGER
*)numericAttributePtr
=SQL_ATTR_READWRITE_UNKNOWN
;
1326 case SQL_DESC_AUTO_UNIQUE_VALUE
:
1327 if(numericAttributePtr
!= NULL
)
1328 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1330 case SQL_DESC_CASE_SENSITIVE
:
1331 if(numericAttributePtr
!= NULL
)
1333 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1334 if((sqlType
!= SQL_CHAR
) && (sqlType
!= SQL_VARCHAR
))
1335 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1337 *(SQLINTEGER
*)numericAttributePtr
=SQL_TRUE
;
1340 case SQL_DESC_SEARCHABLE
:
1341 if(numericAttributePtr
!= NULL
)
1343 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1344 if((sqlType
!= SQL_CHAR
) && (sqlType
!= SQL_VARCHAR
))
1345 *(SQLINTEGER
*)numericAttributePtr
=SQL_PRED_BASIC
;
1347 *(SQLINTEGER
*)numericAttributePtr
=SQL_PRED_SEARCHABLE
;
1353 if(stringLengthPtr
!= NULL
)
1355 if(*stringLengthPtr
> bufferLength
)
1357 err_
.set( ERROR_DATATRUNC
);
1358 return( SQL_SUCCESS_WITH_INFO
);
1361 return( SQL_SUCCESS
);
1364 SQLRETURN
SQLNumParams(
1365 SQLHSTMT StatementHandle
,
1366 SQLSMALLINT
* ParameterCountPtr
)
1369 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1370 return( SQL_INVALID_HANDLE
);
1372 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLNumParams(ParameterCountPtr
) );
1375 SQLRETURN
CSqlOdbcStmt::SQLNumParams(
1376 SQLSMALLINT
* ParameterCount
)
1378 // Start with NO_ERR
1382 if( chkStateForSQLNumParams() != SQL_SUCCESS
)
1383 return( SQL_ERROR
);
1384 if(ParameterCount
== NULL
)
1386 *ParameterCount
=fsqlStmt_
->noOfParamFields();
1391 SQLRETURN
SQLDescribeParam(
1392 SQLHSTMT StatementHandle
,
1393 SQLUSMALLINT ParameterNumber
,
1394 SQLSMALLINT
* DataTypePtr
,
1395 SQLUINTEGER
* ParameterSizePtr
,
1396 SQLSMALLINT
* DecimalDigitsPtr
,
1397 SQLSMALLINT
* NullablePtr
)
1400 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1401 return( SQL_INVALID_HANDLE
);
1403 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLDescribeParam(ParameterNumber
,DataTypePtr
,
1404 ParameterSizePtr
,DecimalDigitsPtr
,NullablePtr
) );
1406 SQLRETURN
CSqlOdbcStmt::SQLDescribeParam(
1407 SQLUSMALLINT paramNumber
,
1408 SQLSMALLINT
* dataType
,
1409 SQLUINTEGER
* paramSize
,
1410 SQLSMALLINT
* decimalDigits
,
1411 SQLSMALLINT
* isNullable
)
1414 // Start with NO_ERR
1418 if( chkStateForSQLDescribeParam() != SQL_SUCCESS
)
1419 return( SQL_ERROR
);
1421 if( paramNumber
< 1 )
1423 err_
.set( ERROR_PARAMNUM
);
1424 return( SQL_ERROR
);
1427 //CSqlOdbcError::printDbg("proxy:stmt:getMetaData");
1428 //CSqlParamMetaData *paramMetaData = fsqlStmt_->getParamMetaData();
1429 if(paramNumber
> fsqlStmt_
->noOfParamFields())
1431 err_
.set( ERROR_PARAMNUM
);
1432 return( SQL_ERROR
);
1435 FieldInfo
*finfo
= new FieldInfo();
1436 if( fsqlStmt_
->getParamFldInfo( paramNumber
-1, finfo
) != OK
) return( SQL_ERROR
);
1437 if(dataType
!= NULL
)
1438 *dataType
= (SQLSMALLINT
) getSQLType(finfo
->type
);
1439 if(paramSize
!= NULL
)
1441 *paramSize
= (SQLUINTEGER
) finfo
->length
;
1442 SQLSMALLINT sqlType
=getSQLType(finfo
->type
);
1443 if(sqlType
== SQL_CHAR
)
1444 *paramSize
= *paramSize
-1;
1446 /*if(decimalDigits != NULL) // CSQL TODO
1447 *decimalDigits = (SQLSMALLINT) paramMetaData->getPrecision( paramNumber-1 );
1448 if(isNullable != NULL)
1449 *isNullable = paramMetaData->isNullable( paramNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1450 return( SQL_SUCCESS
);
1453 // Resets the Stmt to initial state. As if newly allocated.
1454 void CSqlOdbcStmt::resetStmt( void ) // TO DO
1456 SQLFreeStmt( SQL_CLOSE
);
1457 SQLFreeStmt( SQL_UNBIND
);
1458 SQLFreeStmt( SQL_RESET_PARAMS
);
1459 if (fsqlStmt_
) fsqlStmt_
->free();
1462 isPrepared_
= false;