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 if( inputStmt
->parentDbc_
->state_
== C5
)
103 inputStmt
->parentDbc_
->state_
= C4
;
105 inputStmt
->handleType_
= -1; // Make object invalid.
106 delete inputStmt
; // Delete Stmt.
108 return( SQL_SUCCESS
);
111 SQLRETURN
SQLFreeStmt(
112 SQLHSTMT StatementHandle
, // IN
113 SQLUSMALLINT Option
) // IN
116 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
117 return( SQL_INVALID_HANDLE
);
120 if( Option
== SQL_DROP
)
121 return( CSqlOdbcStmt::SQLFreeHandle( StatementHandle
) );
123 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLFreeStmt( Option
) );
126 SQLRETURN
CSqlOdbcStmt::SQLFreeStmt(
133 if( chkStateForSQLFreeStmt() != SQL_SUCCESS
)
135 if (!fsqlStmt_
) return (SQL_SUCCESS
);
138 case SQL_CLOSE
: // // Free resultset
139 // if( fsqlStmt_->isSelect() == true ) // CSQL
141 // //CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
142 // CSqlResultSet *resultSet_ = fsqlStmt_->getResultSet(); // CSQL
143 // if( resultSet_ && resultSet_->isOpen() == true )
145 // resultSet_->close();
152 if( fsqlStmt_
->isSelect() == true ) // CSQL
153 state_
= S3
; // With Cursor
155 state_
= S2
; // Without Cursor
163 fsqlStmt_
->free(); // CSQL
169 case SQL_UNBIND
: ard_
.freeAllDesc();
173 case SQL_RESET_PARAMS
: apd_
.freeAllDesc();
175 //isParamBound_ = false;
178 default: err_
.set( ERROR_OPTRANGE
);
181 return( SQL_SUCCESS
);
184 SQLRETURN
SQLBindCol(
185 SQLHSTMT StatementHandle
,
186 SQLUSMALLINT ColumnNumber
,
187 SQLSMALLINT TargetType
,
188 SQLPOINTER TargetValue
,
189 SQLINTEGER BufferLength
,
190 SQLINTEGER
*StrLen_or_Ind
)
193 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
194 return( SQL_INVALID_HANDLE
);
196 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLBindCol( ColumnNumber
,
197 TargetType
, TargetValue
, BufferLength
, StrLen_or_Ind
) );
200 SQLRETURN
CSqlOdbcStmt::SQLBindCol(
201 SQLUSMALLINT columnNumber
,
202 SQLSMALLINT targetType
,
203 SQLPOINTER targetValue
,
204 SQLINTEGER bufferLength
,
207 CSqlOdbcDesc
*bindDesc
= 0;
208 CSqlOdbcDesc
*inputDesc
= 0;
209 SQLRETURN found
= SQL_ERROR
;
215 if( chkStateForSQLBindCol() != SQL_SUCCESS
)
218 // Invalid Buffer Length.
221 // switch is in order to support more types.
223 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
225 err_
.set( ERROR_BUFLEN
);
230 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
232 err_
.set( ERROR_BUFLEN
);
238 // Invalid Column Number
239 if( columnNumber
< 1 )
241 err_
.set( ERROR_COLNUM
);
245 // Get the Descriptor if already exists
246 found
= ard_
.getDescWithColNum( columnNumber
, &bindDesc
);
249 if( targetValue
== 0 )
251 if( found
!= SQL_SUCCESS
)
253 err_
.set( ERROR_COLNUM
);
256 ard_
.delDesc( bindDesc
); // UNBIND
258 return( SQL_SUCCESS
);
261 // Validate target Type, Value and Column no.
262 if( targetValue
== 0 || isValidCType( targetType
) != SQL_SUCCESS
)
264 err_
.set( ERROR_INVBUFTYPE
);
268 // Add new descriptor
269 if( found
!= SQL_SUCCESS
)
271 bindDesc
= new CSqlOdbcDesc();
272 ard_
.insert( ard_
.begin(), bindDesc
);
275 // Initialize Descriptor.
276 bindDesc
->col_
= columnNumber
;
277 bindDesc
->cType_
= targetType
;
278 bindDesc
->dataPtr_
= targetValue
;
279 bindDesc
->length_
= (SQLUINTEGER
) bufferLength
;
280 bindDesc
->indPtr_
= (SQLPOINTER
) ind
;
282 found
= ird_
.getDescWithColNum( columnNumber
, &inputDesc
);
284 // Add new descriptor
285 if( found
!= SQL_SUCCESS
)
287 inputDesc
= new CSqlOdbcDesc();
288 ird_
.insert(ird_
.begin(),inputDesc
);
291 // Initialize input Descriptor.
292 DataType sourceType
= getCSqlType( targetType
);
293 inputDesc
->col_
= columnNumber
;
294 inputDesc
->cType_
= targetType
;
295 getInputBuffer(&inputDesc
->dataPtr_
,sourceType
,(SQLUINTEGER
) bufferLength
);
296 inputDesc
->length_
= (SQLUINTEGER
) bufferLength
;
297 inputDesc
->indPtr_
= (SQLPOINTER
) ind
;
299 return( SQL_SUCCESS
);
302 SQLRETURN
SQLSetParam(
303 SQLHSTMT StatementHandle
,
304 SQLUSMALLINT ParameterNumber
,
305 SQLSMALLINT ValueType
,
306 SQLSMALLINT ParameterType
,
307 SQLUINTEGER LengthPrecision
,
308 SQLSMALLINT ParameterScale
,
309 SQLPOINTER ParameterValue
,
310 SQLINTEGER
*StrLen_or_Ind
)
312 return( SQLBindParameter( StatementHandle
, ParameterNumber
,
313 SQL_PARAM_INPUT_OUTPUT
, ValueType
, ParameterType
, LengthPrecision
,
314 ParameterScale
, ParameterValue
, 0, StrLen_or_Ind
) );
317 SQLRETURN
SQLBindParam(
318 SQLHSTMT StatementHandle
,
319 SQLUSMALLINT ParameterNumber
,
320 SQLSMALLINT ValueType
,
321 SQLSMALLINT ParameterType
,
322 SQLUINTEGER LengthPrecision
,
323 SQLSMALLINT ParameterScale
,
324 SQLPOINTER ParameterValue
,
325 SQLINTEGER
*StrLen_or_Ind
)
327 return( SQLBindParameter( StatementHandle
, ParameterNumber
,
328 SQL_PARAM_INPUT_OUTPUT
, ValueType
, ParameterType
, LengthPrecision
,
329 ParameterScale
, ParameterValue
, 0, StrLen_or_Ind
) );
332 SQLRETURN
SQLBindParameter(
333 SQLHSTMT StatementHandle
,
334 SQLUSMALLINT ParameterNumber
,
335 SQLSMALLINT InputOutputType
,
336 SQLSMALLINT ValueType
,
337 SQLSMALLINT ParameterType
,
338 SQLUINTEGER LengthPrecision
,
339 SQLSMALLINT ParameterScale
,
340 SQLPOINTER ParameterValue
,
341 SQLINTEGER BufferLength
,
342 SQLINTEGER
*StrLen_or_Ind
)
345 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
346 return( SQL_INVALID_HANDLE
);
348 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLBindParameter( ParameterNumber
,
349 InputOutputType
, ValueType
,
350 ParameterType
, LengthPrecision
,
351 ParameterScale
, ParameterValue
,
352 BufferLength
, StrLen_or_Ind
) );
355 SQLRETURN
CSqlOdbcStmt::SQLBindParameter(
356 SQLUSMALLINT parameterNumber
,
357 SQLSMALLINT inputOutputType
,
358 SQLSMALLINT valueType
,
359 SQLSMALLINT parameterType
,
360 SQLUINTEGER lengthPrecision
,
361 SQLSMALLINT parameterScale
,
362 SQLPOINTER parameterValue
,
363 SQLINTEGER bufferLength
,
366 CSqlOdbcDesc
*bindDesc
= 0;
367 CSqlOdbcDesc
*inputDesc
=0;
374 if( chkStateForSQLBindParameter() != SQL_SUCCESS
)
377 // Invalid Buffer Length.
380 // switch is in order to support more types.
382 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
384 err_
.set( ERROR_BUFLEN
);
389 if( bufferLength
< 0 && bufferLength
!= SQL_NTS
)
391 err_
.set( ERROR_BUFLEN
);
397 // Validate parameters
398 switch( inputOutputType
)
400 case SQL_PARAM_INPUT
:
401 case SQL_PARAM_OUTPUT
:
402 case SQL_PARAM_INPUT_OUTPUT
: break;
403 default: err_
.set( ERROR_INV_PARAMTYPE
);
406 if( isValidCType( valueType
) != SQL_SUCCESS
||
407 isValidSQLType( parameterType
) != SQL_SUCCESS
)
409 err_
.set( ERROR_INVBUFTYPE
);
412 if( parameterNumber
< 1 )
414 err_
.set( ERROR_COLNUM
);
418 // Get the Descriptor if already exists
419 found
= apd_
.getDescWithColNum( parameterNumber
, &bindDesc
);
420 if( found
!= SQL_SUCCESS
)
422 bindDesc
= new CSqlOdbcDesc();
423 apd_
.insert( apd_
.end(), bindDesc
);
424 // Initialize Descriptor.
425 bindDesc
->col_
= parameterNumber
;
426 bindDesc
->paramType_
= inputOutputType
;
427 bindDesc
->cType_
= valueType
;
428 bindDesc
->sqlType_
= parameterType
;
429 bindDesc
->dataPtr_
= parameterValue
;
430 bindDesc
->length_
= (SQLUINTEGER
) bufferLength
;
431 bindDesc
->precision_
=(short) lengthPrecision
;
432 bindDesc
->scale_
= parameterScale
;
433 bindDesc
->indPtr_
= (SQLPOINTER
) ind
;
435 found
= ipd_
.getDescWithColNum (parameterNumber
, &inputDesc
);
436 if( found
!= SQL_SUCCESS
)
438 inputDesc
= new CSqlOdbcDesc();
439 ipd_
.insert(ipd_
.end(),inputDesc
);
440 //Initialize inputDescriptor
441 DataType destType
=getCSqlType(valueType
);
442 inputDesc
->col_
= parameterNumber
;
443 inputDesc
->paramType_
= inputOutputType
;
444 inputDesc
->cType_
= valueType
;
445 inputDesc
->sqlType_
= parameterType
;
446 inputDesc
->dataPtr_
= NULL
;
447 //getInputBuffer(&inputDesc->dataPtr_,destType,(SQLUINTEGER)bufferLength);
448 inputDesc
->length_
= (SQLUINTEGER
) bufferLength
;
449 inputDesc
->precision_
= (short)lengthPrecision
;
450 inputDesc
->scale_
= parameterScale
;
451 inputDesc
->indPtr_
= (SQLPOINTER
) ind
;
453 //isParamBound_ = false;
454 return( SQL_SUCCESS
);
457 SQLRETURN
SQLPrepare(
458 SQLHSTMT StatementHandle
, // IN
459 SQLCHAR
*StatementText
, // IN
460 SQLINTEGER TextLength
) // IN
463 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
464 return( SQL_INVALID_HANDLE
);
467 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLPrepare( StatementText
, TextLength
) );
470 SQLRETURN
CSqlOdbcStmt::SQLPrepare(
471 SQLCHAR
*statementText
, // IN
472 SQLINTEGER textLength
) // IN
478 if( chkStateForSQLPrepare() != SQL_SUCCESS
)
481 // Invalid Buffer Length.
482 if( textLength
< 0 && textLength
!= SQL_NTS
)
484 err_
.set( ERROR_BUFLEN
);
488 // If Stmt is already prepared.
493 if (parentDbc_
->mode_
==1)
494 fsqlStmt_
= SqlFactory::createStatement(CSql
);
495 else if (parentDbc_
->mode_
==2)
496 fsqlStmt_
= SqlFactory::createStatement(CSqlGateway
);
497 else if (parentDbc_
->mode_
==3)
498 fsqlStmt_
= SqlFactory::createStatement(CSqlAdapter
);
499 fsqlStmt_
->setConnection( parentDbc_
->fsqlConn_
);
502 //CSqlOdbcError::printDbg("proxy:stmt:prepare");
504 if( (rv
=fsqlStmt_
->prepare( (char*) statementText
))!= OK
) // CSQL
507 err_
.set(ERROR_GENERAL
);
510 case csqlSqlErrSchNotFound: err_.set( ERROR_SCHNOTFOUND); break;
511 case csqlSqlErrTblNotFound: err_.set( ERROR_TBLNOTFOUND); break;
512 case csqlSqlErrFldNotFound: err_.set( ERROR_NO_COLEXISTS); break;
513 case csqlSqlErrIndexNotFound: err_.set( ERROR_NO_IDXEXISTS); break;
514 case csqlSqlErrViewNotFound: err_.set( ERROR_TBLNOTFOUND); break;
515 case csqlSqlErrTblExists: err_.set( ERROR_TBLEXISTS); break;
516 case csqlSqlErrFldExists: err_.set( ERROR_COLEXISTS); break;
517 case csqlSqlErrIndexExists: err_.set( ERROR_IDXEXISTS); break;
518 case csqlSqlErrViewExists: err_.set( ERROR_TBLEXISTS); break;
519 case csqlSqlErrTooManyVals:err_.set(ERROR_MANY_VALS);break;
520 case csqlSqlErrTooFewVals:err_.set(ERROR_FEW_VALS);break;
521 case csqlSqlErrSqlSyntaxError:err_.set(ERROR_SQL_SYNTAX);break;
522 case csqlSqlErrIncompatibleType:err_.set(ERROR_TYPE_INCMP);break;
523 case csqlSqlErrInvalidFormat:err_.set(ERROR_DATA_FORMAT);break;
524 case csqlSqlErrDuplicateFld:err_.set(ERROR_DUP_COL);break;
525 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
530 if( fsqlStmt_
->isSelect() != true ) // CSQL
531 state_
= S2
; // With cursor
533 state_
= S3
; // Without cursor
535 //parentDbc_->state_ = C6;
537 return( SQL_SUCCESS
);
540 SQLRETURN
SQLExecute(SQLHSTMT StatementHandle
) // IN
543 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
544 return( SQL_INVALID_HANDLE
);
546 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLExecute() );
549 SQLRETURN
CSqlOdbcStmt::SQLExecute() // TODO
555 if( chkStateForSQLExecute() != SQL_SUCCESS
)
558 if( fsqlStmt_
->noOfParamFields() > 0 )
561 // Iterate through all apd_;
562 CSqlOdbcDesc
*appParamDesc
;
563 CSqlOdbcDescList::iterator apdIter
;
564 apdIter
= apd_
.begin();
565 CSqlOdbcDesc
*csqlParamDesc
;
566 CSqlOdbcDescList::iterator ipdIter
;
567 ipdIter
= ipd_
.begin();
569 //Get the source and the destination type
570 DataType sourceType
= typeUnknown
,destType
= typeUnknown
;
571 int paramNum
=1,sourceLength
=-1,destLength
=-1;
574 while( (apdIter
!= apd_
.end()) || (ipdIter
!= ipd_
.end()) )
576 appParamDesc
=*apdIter
;
577 csqlParamDesc
=*ipdIter
;
578 if((paramNum
) <= fsqlStmt_
->noOfParamFields())
580 FieldInfo
*finfo
= new FieldInfo();
581 if( fsqlStmt_
->getParamFldInfo(paramNum
, finfo
) != OK
) return( SQL_ERROR
);
582 sourceType
=getCSqlType(appParamDesc
->cType_
);
583 destType
=finfo
->type
;
584 sourceLength
=(int)appParamDesc
->length_
;
585 destLength
=finfo
->length
;
587 if(sourceType
!= typeUnknown
&& destType
!= typeUnknown
)
589 //Check if NULL is inserted
590 if((appParamDesc
->indPtr_
!= NULL
) && (*(SQLINTEGER
*)appParamDesc
->indPtr_
) == SQL_NULL_DATA
)
593 //finfo->isNull = true; CSQL TODO - need to understand how to set null
597 //Only if both types are not the same, then we need to copy it onto intermediate buffer
599 if( (sourceType
== typeString
|| sourceType
== typeBinary
) && (sourceLength
<= 0))
601 if((appParamDesc
->indPtr_
!= NULL
) && *(SQLINTEGER
*)appParamDesc
->indPtr_
> 0)
602 sourceLength
=(int)(*(SQLINTEGER
*)appParamDesc
->indPtr_
);
603 else if (appParamDesc
->precision_
> 0)
604 sourceLength
=appParamDesc
->precision_
;
607 err_
.set( ERROR_BUFLEN
);
611 if(destType
== typeString
) //|| destType == typeVarString)
613 //fsqlStmt_->allocParam(paramNum,sourceLength); // CSQL TODO
614 destLength
=sourceLength
;
616 if(sourceType
== destType
)
617 //|| (sourceType == typeString && destType == typeVarString)
618 //|| (sourceType == typeBinary && destType == typeVarBinary))
620 copyFromOdbc(fsqlStmt_
, paramNum
, destLength
, appParamDesc
->dataPtr_
, sourceLength
,destType
); // CSQL TODO
623 getInputBuffer(&csqlParamDesc
->dataPtr_
,sourceType
,sourceLength
);
624 copyFromOdbc(fsqlStmt_
, paramNum
, destLength
, appParamDesc
->dataPtr_
, sourceLength
, sourceType
);
625 //convert(sourceType,csqlParamDesc->dataPtr_,destType, fsqlStmt_->getParamPtr( paramNum),sourceLength,destLength); // CSQL TODO
631 err_
.set(ERROR_GENERAL
);
644 DbRetVal rv
= fsqlStmt_
->execute( rowsAffected
);
645 if( rowsAffected
< 0 )
647 if( isPrepared_
) state_
= S2
; else resetStmt();
648 err_
.set( ERROR_GENERAL
);
651 case csqlSqlErrOverflow:err_.set(ERROR_OVERFLOW);break;
652 case csqlSqlErrUnderflow:err_.set(ERROR_UNDERFLOW);break;
653 case csqlSqlErrTooManyTpl:err_.set(ERROR_MANY_TUP);break;
654 case csqlSqlErrProjCnt:err_.set(ERROR_NUM_PROJ);break;
655 case csqlSqlErrStorageAttr:err_.set(ERROR_STORAGE_ATTR);break;
656 case csqlSqlErrFldCntMismatch:err_.set(ERROR_FLDCNT_MISMATCH);break;
657 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
658 case csqlSqlErrNoMatchKeyFound:err_.set(ERROR_MATCHKEY_NOTFOUND);break;
660 err_.set( ERROR_GENERAL );break;
666 if( fsqlStmt_
->isSelect() == true )
673 rowsAffected_
= rowsAffected
;
677 // Set Dbc State to Transaction Mode.
678 parentDbc_
->state_
= C6
;
681 if( parentDbc_
->autoCommit_
== SQL_AUTOCOMMIT_ON
)
682 parentDbc_
->SQLEndTran( SQL_COMMIT
);
684 return( SQL_SUCCESS
);
687 SQLRETURN
SQLExecDirect(
688 SQLHSTMT StatementHandle
,
689 SQLCHAR
*StatementText
,
690 SQLINTEGER TextLength
)
693 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
694 return( SQL_INVALID_HANDLE
);
696 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLExecDirect( StatementText
, TextLength
) );
699 SQLRETURN
CSqlOdbcStmt::SQLExecDirect(
700 SQLCHAR
*statementText
,
701 SQLINTEGER textLength
)
706 if( chkStateForSQLExecDirect() != SQL_SUCCESS
)
709 // SQLExecDirect = SQLPrepare + SQLExecute.
710 if( SQLPrepare( statementText
, textLength
) != SQL_SUCCESS
)
714 isPrepared_
= false; // Set Stmt as non-prepared stmt.
716 if( ret
!= SQL_SUCCESS
)
719 return( SQL_SUCCESS
);
722 SQLRETURN
SQLSetStmtOption(
723 SQLHSTMT StatementHandle
,
727 return (SQLSetStmtAttr(StatementHandle
, Option
, (SQLPOINTER
) Value
, 0));
730 SQLRETURN SQL_API
SQLSetStmtAttr(SQLHSTMT StatementHandle
,
731 SQLINTEGER Attribute
, SQLPOINTER Value
,
732 SQLINTEGER StringLength
)
734 return (((CSqlOdbcStmt
*)StatementHandle
)->SQLSetStmtAttr(Attribute
, Value
,StringLength
));
737 SQLRETURN
CSqlOdbcStmt::SQLSetStmtAttr(
738 SQLINTEGER Attribute
,
740 SQLINTEGER stringLength
)
742 CSqlOdbcError::printDbg("proxy:stmt:SQLSetStmtAttr");
746 //Values: SQL_FETCH_SINGLE_TUPLE or SQL_FETCH_MULTIPLE_TUPLES
747 //Default is SQL_FETCH_SINGLE_TUPLE.
748 //In SQL_FETCH_SINGLE_TUPLE mode, only a single tuple
749 //is sent from server to client in a single packet whatever be
750 //the packet size. If a tuple size is 50 and network packet size
751 //is 500, the remaining 450 bytes can also be used to send more
752 //in a single packet so that in the next SQLFetch call one network
753 //packet transfer overhead is reduced.
756 //state_ > S5 means Fetch has already started on this statement.
757 fetchMode_ = (SQLINTEGER)Value;
759 printf("ODBC:Error in setting fetch mode, can't set after fetch is started.\n");
762 printf("ODBC: Error, Stmt Option %d is not supported.\n", Attribute);
764 return (SQL_SUCCESS
);
767 SQLRETURN
SQLFetch(SQLHSTMT StatementHandle
)
770 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
771 return( SQL_INVALID_HANDLE
);
773 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLFetch() );
776 SQLRETURN
CSqlOdbcStmt::SQLFetch()
782 if( chkStateForSQLFetch() != SQL_SUCCESS
)
786 tuple
= fsqlStmt_
->next();
788 if( ! tuple
) // IF Row not found.
792 return( SQL_NO_DATA_FOUND
);
794 /*else if( rowsAffected != SQL_SUCCESS ) // IF Error
797 err_.set( ERROR_GENERAL );
800 else // IF Row found.
804 // Iterate through all ard_;
805 CSqlOdbcDesc
*appColDesc
;
806 CSqlOdbcDescList::iterator ardIter
;
807 ardIter
= ard_
.begin();
808 //Get the input parameter data
809 CSqlOdbcDesc
*csqlColDesc
;
810 CSqlOdbcDescList::iterator irdIter
;
811 irdIter
= ird_
.begin();
813 DataType sourceType
= typeUnknown
,destType
= typeUnknown
;
814 int colNum
=-1,sourceLength
=-1,destLength
=-1;
816 void* sourceData
= NULL
;
817 FieldInfo
*info
= new FieldInfo();
818 while( (ardIter
!= ard_
.end()) || (irdIter
!= ird_
.end()) )
820 appColDesc
= *ardIter
;
821 csqlColDesc
= *irdIter
;
823 colNum
= appColDesc
->col_
- 1;
824 fsqlStmt_
->getProjFldInfo(colNum
, info
);
825 sourceType
= info
->type
;
826 destType
= getCSqlType(appColDesc
->cType_
);
827 sourceLength
= info
->length
;
828 destLength
= (int)appColDesc
->length_
;
830 if( sourceType
!= typeUnknown
&& destType
!= typeUnknown
)
832 sourceData
= fsqlStmt_
->getFieldValuePtr( colNum
);
833 if(sourceData
== NULL
)
835 if (appColDesc
->indPtr_
!= NULL
)
836 *((SQLINTEGER
*)(appColDesc
->indPtr_
))=SQL_NULL_DATA
;
840 /*if( sourceType == csqlSqlTvarBinary)
841 sourceLength=resultSet_->getDataLength(colNum); */
842 if (sourceType
== typeString
) // CSQL TODO - handle varchar also
844 sourceLength
=(int)(strlen((char *) sourceData
));
845 if(appColDesc
->indPtr_
!= NULL
)
846 *((SQLINTEGER
*)(appColDesc
->indPtr_
))=copyToOdbc(appColDesc
->dataPtr_
,destLength
,
847 sourceData
,sourceLength
, sourceType
);
849 copyToOdbc(appColDesc
->dataPtr_
,destLength
,sourceData
,
850 sourceLength
, sourceType
);
854 //convert(sourceType,sourceData,destType, csqlColDesc->dataPtr_,sourceLength,destLength);
855 if(appColDesc
->indPtr_
!= NULL
)
856 *((SQLINTEGER
*)(appColDesc
->indPtr_
))=
857 copyToOdbc(appColDesc
->dataPtr_
,destLength
, sourceData
, sourceLength
, sourceType
);
859 copyToOdbc(appColDesc
->dataPtr_
,destLength
, sourceData
, sourceLength
, sourceType
);
862 // CSQL TODO - handle varstring, binary, varbinary
863 if( sourceType
== typeString
&& sourceLength
> destLength
)
864 err_
.set( ERROR_DATATRUNC
);
872 if(err_
.csqlErrCode
== ERROR_DATATRUNC
)
873 return (SQL_SUCCESS_WITH_INFO
);
875 return( SQL_SUCCESS
);
878 SQLRETURN
SQLCloseCursor(SQLHSTMT StatementHandle
)
881 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
882 return( SQL_INVALID_HANDLE
);
884 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLCloseCursor() );
887 SQLRETURN
CSqlOdbcStmt::SQLCloseCursor()
893 if( chkStateForSQLCloseCursor() != SQL_SUCCESS
)
899 return( SQL_SUCCESS
);
902 SQLRETURN
SQLSetCursorName(
903 SQLHSTMT StatementHandle
,
905 SQLSMALLINT NameLength
)
908 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
909 return( SQL_INVALID_HANDLE
);
911 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLSetCursorName( CursorName
, NameLength
) );
914 SQLRETURN
CSqlOdbcStmt::SQLSetCursorName(
916 SQLSMALLINT nameLength
)
922 if( chkStateForSQLSetCursorName() != SQL_SUCCESS
)
925 // Invalid Stmt Length.
926 if( nameLength
< 0 && nameLength
!= SQL_NTS
)
928 err_
.set( ERROR_INVARGVAL
);
932 // Validate Parameters
933 if( cursorName
== 0 || cursorName
[0] == '\0' || strlen( (char*) cursorName
) > SQL_MAX_CURSOR_NAME_LEN
||
934 nameLength
> SQL_MAX_CURSOR_NAME_LEN
)
936 err_
.set( ERROR_CURNAME
);
940 // Check for duplicate Name
941 std::vector
<CSqlOdbcStmt
*>::iterator iter
;
942 iter
= parentDbc_
->stmtList_
.begin();
943 while( iter
!= parentDbc_
->stmtList_
.end() )
947 if( strcmp( (char*) cursorName
, (char*) (*iter
)->cursorName_
) == 0 )
949 err_
.set( ERROR_DUP_CURNAME
);
957 strcpy( (char*) cursorName_
, (char*) cursorName
);
959 return( SQL_SUCCESS
);
962 SQLRETURN
SQLGetCursorName(
963 SQLHSTMT StatementHandle
,
965 SQLSMALLINT BufferLength
,
966 SQLSMALLINT
*NameLength
)
969 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
970 return( SQL_INVALID_HANDLE
);
972 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLGetCursorName( CursorName
, BufferLength
, NameLength
) );
974 SQLRETURN
CSqlOdbcStmt::SQLGetCursorName(
976 SQLSMALLINT bufferLength
,
977 SQLSMALLINT
*nameLength
)
980 if( chkStateForSQLGetCursorName() != SQL_SUCCESS
)
983 if( cursorName_
[0] == '\0' )
985 err_
.set( ERROR_NOCURNAME
);
990 *nameLength
= (short)strlen( (char*) cursorName_
);
991 if( *nameLength
> bufferLength
) *nameLength
= bufferLength
;
992 strncpy( (char*) cursorName
, (char*) cursorName_
, *nameLength
);
993 cursorName
[ *nameLength
] = '\0';
996 if( bufferLength
< strlen( (char*) cursorName_
) )
998 err_
.set( ERROR_DATATRUNC
);
999 return( SQL_SUCCESS_WITH_INFO
);
1002 return( SQL_SUCCESS
);
1005 SQLRETURN
SQLNumResultCols(
1006 SQLHSTMT StatementHandle
, // IN
1007 SQLSMALLINT
*ColumnCount
) // OUT
1010 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1011 return( SQL_INVALID_HANDLE
);
1013 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLNumResultCols( ColumnCount
) );
1016 SQLRETURN
CSqlOdbcStmt::SQLNumResultCols(
1017 SQLSMALLINT
*columnCount
) // OUT
1019 // Start with NO_ERR
1023 if( chkStateForSQLNumResultCols() != SQL_SUCCESS
)
1024 return( SQL_ERROR
);
1027 if( fsqlStmt_
->isSelect() == false )
1030 return (SQL_SUCCESS
);
1034 SQLSMALLINT count
= fsqlStmt_
->noOfProjFields();
1035 if( count
< 1 ) // Assume atleast one column is projected
1036 return( SQL_ERROR
);
1038 // Fill Column Count
1039 *columnCount
= count
;
1041 return( SQL_SUCCESS
);
1044 SQLRETURN SQL_API
SQLRowCount(
1045 SQLHSTMT StatementHandle
, // IN
1046 SQLINTEGER
*RowCount
) // OUT
1049 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1050 return( SQL_INVALID_HANDLE
);
1052 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLRowCount( RowCount
) );
1055 SQLRETURN
CSqlOdbcStmt::SQLRowCount(
1056 SQLINTEGER
*rowCount
) // OUT
1058 // Start with NO_ERR
1062 if( chkStateForSQLRowCount() != SQL_SUCCESS
)
1063 return( SQL_ERROR
);
1065 if(rowCount
== NULL
)
1068 if( state_
== S4
) // For INSERT/DELETE/UPDATE
1069 *rowCount
= (SQLINTEGER
) rowsAffected_
;
1070 else if( state_
== S5
) // For SELECT before SQLFetch()
1072 *rowCount
= (SQLINTEGER
) 0;
1073 // CSQL TODO - Think if you really want to do this!!!
1075 /*CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
1076 CSqlResultSet *resultSet_ = fsqlStmt_.getResultSet();
1077 if( resultSet_->next() != csqlSqlErrNoTuple )
1078 *rowCount = (SQLINTEGER) 1;
1080 resultSet_->close();
1081 resultSet_->open(); */
1083 else if( state_
== S6
) // For SELECT after SQLFetch();
1084 *rowCount
= (SQLINTEGER
) rowsAffected_
;
1086 return( SQL_SUCCESS
);
1089 SQLRETURN
SQLDescribeCol(
1090 SQLHSTMT StatementHandle
,
1091 SQLUSMALLINT ColumnNumber
,
1092 SQLCHAR
*ColumnName
,
1093 SQLSMALLINT BufferLength
,
1094 SQLSMALLINT
*NameLength
,
1095 SQLSMALLINT
*DataType
,
1096 SQLUINTEGER
*ColumnSize
,
1097 SQLSMALLINT
*DecimalDigits
,
1098 SQLSMALLINT
*Nullable
)
1101 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1102 return( SQL_INVALID_HANDLE
);
1104 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLDescribeCol( ColumnNumber
, ColumnName
, BufferLength
,
1105 NameLength
, DataType
, ColumnSize
, DecimalDigits
, Nullable
) );
1108 SQLRETURN
CSqlOdbcStmt::SQLDescribeCol(
1109 SQLUSMALLINT columnNumber
,
1110 SQLCHAR
*columnName
,
1111 SQLSMALLINT bufferLength
,
1112 SQLSMALLINT
*nameLength
,
1113 SQLSMALLINT
*dataType
,
1114 SQLUINTEGER
*columnSize
,
1115 SQLSMALLINT
*decimalDigits
,
1116 SQLSMALLINT
*nullable
)
1124 // Start with NO_ERR
1128 if( chkStateForSQLDescribeCol() != SQL_SUCCESS
)
1129 return( SQL_ERROR
);
1131 if( columnNumber
< 1 )
1133 err_
.set( ERROR_COLNUM
);
1134 return( SQL_ERROR
);
1138 if( fsqlStmt_
->isSelect() == false )
1139 return( SQL_ERROR
);
1142 if(columnNumber
> fsqlStmt_
->noOfProjFields())
1144 err_
.set( ERROR_COLNUM
);
1145 return( SQL_ERROR
);
1147 if(columnName
== NULL
) {
1148 err_
.set( ERROR_COLNUM
);
1149 return( SQL_ERROR
);
1151 FieldInfo
*info
= new FieldInfo();
1152 fsqlStmt_
->getProjFldInfo(columnNumber
, info
);
1153 strncpy( (char*)columnName
, (char*)info
->fldName
, bufferLength
);
1154 if(nameLength
!= NULL
)
1155 *nameLength
=(short)strlen((const char*)info
->fldName
); // HARDCODED - TO DO, need support for n/w layer & sql layer
1156 if(dataType
!= NULL
)
1157 *dataType
= (SQLSMALLINT
) getSQLType(info
->type
); // Need to convert from SQL<->ODBC - TO DO
1158 if(columnSize
!= NULL
)
1160 *columnSize
= (SQLUINTEGER
) info
->length
;
1161 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1162 if(sqlType
== SQL_CHAR
)
1163 *columnSize
= *columnSize
-1;
1166 /*if(decimalDigits != NULL) // CSQL TODO
1167 *decimalDigits = (SQLSMALLINT) fsqlStmt_->getPrecision( columnNumber-1 );
1168 if(nullable != NULL)
1169 *nullable = rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N; */
1170 if(strlen((char*)info
->fldName
) > bufferLength
)
1172 err_
.set( ERROR_DATATRUNC
);
1173 return( SQL_SUCCESS_WITH_INFO
);
1176 return( SQL_SUCCESS
);
1179 SQLRETURN
SQLColAttributes(
1180 SQLHSTMT StatementHandle
,
1181 SQLUSMALLINT ColumnNumber
,
1182 SQLUSMALLINT FieldIdentifier
,
1183 SQLPOINTER CharacterAttributePtr
,
1184 SQLSMALLINT BufferLength
,
1185 SQLSMALLINT
*StringLengthPtr
,
1186 SQLINTEGER
*NumericAttributePtr
)
1189 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1190 return( SQL_INVALID_HANDLE
);
1192 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLColAttribute(ColumnNumber
,FieldIdentifier
,
1193 CharacterAttributePtr
, BufferLength
, StringLengthPtr
, (SQLPOINTER
)NumericAttributePtr
) );
1196 SQLRETURN
SQLColAttribute(
1197 SQLHSTMT StatementHandle
,
1198 SQLUSMALLINT ColumnNumber
,
1199 SQLUSMALLINT FieldIdentifier
,
1200 SQLPOINTER CharacterAttributePtr
,
1201 SQLSMALLINT BufferLength
,
1202 SQLSMALLINT
* StringLengthPtr
,
1203 SQLPOINTER NumericAttributePtr
)
1206 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1207 return( SQL_INVALID_HANDLE
);
1209 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLColAttribute(ColumnNumber
,FieldIdentifier
,
1210 CharacterAttributePtr
, BufferLength
, StringLengthPtr
, NumericAttributePtr
) );
1213 SQLRETURN
CSqlOdbcStmt::SQLColAttribute(
1214 SQLUSMALLINT columnNumber
,
1215 SQLUSMALLINT fieldIdentifier
,
1216 SQLPOINTER characterAttributePtr
,
1217 SQLSMALLINT bufferLength
,
1218 SQLSMALLINT
* stringLengthPtr
,
1219 SQLPOINTER numericAttributePtr
)
1227 // Start with NO_ERR
1231 if( chkStateForSQLDescribeCol() != SQL_SUCCESS
)
1232 return( SQL_ERROR
);
1234 if( columnNumber
< 1 )
1236 err_
.set( ERROR_COLNUM
);
1237 return( SQL_ERROR
);
1240 if( fsqlStmt_
->isSelect() == false )
1241 return( SQL_ERROR
);
1243 FieldInfo
*info
= new FieldInfo();
1244 fsqlStmt_
->getProjFldInfo(columnNumber
, info
);
1247 if(columnNumber
> fsqlStmt_
->noOfProjFields())
1249 err_
.set( ERROR_COLNUM
);
1250 return( SQL_ERROR
);
1252 switch(fieldIdentifier
)
1255 case SQL_COLUMN_NAME
:
1256 if(characterAttributePtr
!= NULL
)
1258 strncpy( (char*)characterAttributePtr
, (char*)info
->fldName
, bufferLength
);
1259 if(stringLengthPtr
!= NULL
)
1260 *stringLengthPtr
=(short)strlen((char*)info
->fldName
);
1263 case SQL_DESC_COUNT
:
1264 case SQL_COLUMN_COUNT
:
1265 if(numericAttributePtr
!= NULL
)
1266 *(SQLINTEGER
*)numericAttributePtr
=fsqlStmt_
->noOfProjFields();
1269 case SQL_COLUMN_TYPE
:
1270 if(numericAttributePtr
!= NULL
)
1271 *(SQLINTEGER
*)numericAttributePtr
=getSQLType(info
->type
);
1273 case SQL_DESC_LENGTH
:
1274 case SQL_COLUMN_LENGTH
:
1275 if(numericAttributePtr
!= NULL
)
1277 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1278 *(SQLINTEGER
*)numericAttributePtr
=(SQLUINTEGER
) info
->length
;
1279 if(sqlType
== SQL_CHAR
)
1280 *(SQLINTEGER
*)numericAttributePtr
=*(SQLINTEGER
*)numericAttributePtr
-1;
1283 case SQL_DESC_PRECISION
:
1284 case SQL_COLUMN_PRECISION
:
1285 /*if(numericAttributePtr != NULL) // CSQL TODO
1286 *(SQLINTEGER *)numericAttributePtr=(SQLSMALLINT) rsMetaData->getPrecision( columnNumber-1 ); */
1288 case SQL_DESC_SCALE
:
1289 case SQL_COLUMN_SCALE
:
1290 /*if(numericAttributePtr != NULL) // CSQL TODO
1291 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->getScale( columnNumber-1 );*/
1293 case SQL_DESC_NULLABLE
:
1294 case SQL_COLUMN_NULLABLE
:
1295 /*if(numericAttributePtr != NULL) // CSQL TODO
1296 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1298 case SQL_DESC_UNSIGNED
:
1299 if(numericAttributePtr
!= NULL
)
1301 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1302 if((sqlType
!= SQL_TIME
) && (sqlType
!= SQL_DATE
) && (sqlType
!= SQL_TIMESTAMP
)
1303 && (sqlType
!= SQL_CHAR
) && (sqlType
!= SQL_VARCHAR
) && (sqlType
!= SQL_BINARY
)
1304 && (sqlType
!= SQL_VARBINARY
) && (sqlType
!= SQL_BIT
))
1305 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1307 *(SQLINTEGER
*)numericAttributePtr
=SQL_TRUE
;
1310 case SQL_DESC_FIXED_PREC_SCALE
:
1311 if(numericAttributePtr
!= NULL
)
1312 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1314 case SQL_DESC_TYPE_NAME
:
1315 if(characterAttributePtr
!= NULL
)
1317 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1318 strncpy((char*)characterAttributePtr
,(char *)(getSQLTypeName(sqlType
)),bufferLength
);
1319 if(stringLengthPtr
!= NULL
)
1320 *stringLengthPtr
=(int)strlen((char *)getSQLTypeName(sqlType
));
1323 case SQL_DESC_UPDATABLE
:
1324 if(numericAttributePtr
!= NULL
)
1325 *(SQLINTEGER
*)numericAttributePtr
=SQL_ATTR_READWRITE_UNKNOWN
;
1327 case SQL_DESC_AUTO_UNIQUE_VALUE
:
1328 if(numericAttributePtr
!= NULL
)
1329 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1331 case SQL_DESC_CASE_SENSITIVE
:
1332 if(numericAttributePtr
!= NULL
)
1334 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1335 if((sqlType
!= SQL_CHAR
) && (sqlType
!= SQL_VARCHAR
))
1336 *(SQLINTEGER
*)numericAttributePtr
=SQL_FALSE
;
1338 *(SQLINTEGER
*)numericAttributePtr
=SQL_TRUE
;
1341 case SQL_DESC_SEARCHABLE
:
1342 if(numericAttributePtr
!= NULL
)
1344 SQLSMALLINT sqlType
=getSQLType(info
->type
);
1345 if((sqlType
!= SQL_CHAR
) && (sqlType
!= SQL_VARCHAR
))
1346 *(SQLINTEGER
*)numericAttributePtr
=SQL_PRED_BASIC
;
1348 *(SQLINTEGER
*)numericAttributePtr
=SQL_PRED_SEARCHABLE
;
1354 if(stringLengthPtr
!= NULL
)
1356 if(*stringLengthPtr
> bufferLength
)
1358 err_
.set( ERROR_DATATRUNC
);
1359 return( SQL_SUCCESS_WITH_INFO
);
1362 return( SQL_SUCCESS
);
1365 SQLRETURN
SQLNumParams(
1366 SQLHSTMT StatementHandle
,
1367 SQLSMALLINT
* ParameterCountPtr
)
1370 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1371 return( SQL_INVALID_HANDLE
);
1373 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLNumParams(ParameterCountPtr
) );
1376 SQLRETURN
CSqlOdbcStmt::SQLNumParams(
1377 SQLSMALLINT
* ParameterCount
)
1379 // Start with NO_ERR
1383 if( chkStateForSQLNumParams() != SQL_SUCCESS
)
1384 return( SQL_ERROR
);
1385 if(ParameterCount
== NULL
)
1387 *ParameterCount
=(int)apd_
.size();
1392 SQLRETURN
SQLDescribeParam(
1393 SQLHSTMT StatementHandle
,
1394 SQLUSMALLINT ParameterNumber
,
1395 SQLSMALLINT
* DataTypePtr
,
1396 SQLUINTEGER
* ParameterSizePtr
,
1397 SQLSMALLINT
* DecimalDigitsPtr
,
1398 SQLSMALLINT
* NullablePtr
)
1401 if( isValidHandle( (CSqlOdbcStmt
*) StatementHandle
, SQL_HANDLE_STMT
) != SQL_SUCCESS
)
1402 return( SQL_INVALID_HANDLE
);
1404 return( ((CSqlOdbcStmt
*) StatementHandle
)->SQLDescribeParam(ParameterNumber
,DataTypePtr
,
1405 ParameterSizePtr
,DecimalDigitsPtr
,NullablePtr
) );
1407 SQLRETURN
CSqlOdbcStmt::SQLDescribeParam(
1408 SQLUSMALLINT paramNumber
,
1409 SQLSMALLINT
* dataType
,
1410 SQLUINTEGER
* paramSize
,
1411 SQLSMALLINT
* decimalDigits
,
1412 SQLSMALLINT
* isNullable
)
1415 // Start with NO_ERR
1419 if( chkStateForSQLDescribeParam() != SQL_SUCCESS
)
1420 return( SQL_ERROR
);
1422 if( paramNumber
< 1 )
1424 err_
.set( ERROR_PARAMNUM
);
1425 return( SQL_ERROR
);
1428 //CSqlOdbcError::printDbg("proxy:stmt:getMetaData");
1429 //CSqlParamMetaData *paramMetaData = fsqlStmt_->getParamMetaData();
1430 if(paramNumber
> fsqlStmt_
->noOfParamFields())
1432 err_
.set( ERROR_PARAMNUM
);
1433 return( SQL_ERROR
);
1436 FieldInfo
*finfo
= new FieldInfo();
1437 if( fsqlStmt_
->getParamFldInfo( paramNumber
-1, finfo
) != OK
) return( SQL_ERROR
);
1438 if(dataType
!= NULL
)
1439 *dataType
= (SQLSMALLINT
) getSQLType(finfo
->type
);
1440 if(paramSize
!= NULL
)
1442 *paramSize
= (SQLUINTEGER
) finfo
->length
;
1443 SQLSMALLINT sqlType
=getSQLType(finfo
->type
);
1444 if(sqlType
== SQL_CHAR
)
1445 *paramSize
= *paramSize
-1;
1447 /*if(decimalDigits != NULL) // CSQL TODO
1448 *decimalDigits = (SQLSMALLINT) paramMetaData->getPrecision( paramNumber-1 );
1449 if(isNullable != NULL)
1450 *isNullable = paramMetaData->isNullable( paramNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1451 return( SQL_SUCCESS
);
1454 // Resets the Stmt to initial state. As if newly allocated.
1455 void CSqlOdbcStmt::resetStmt( void ) // TO DO
1457 SQLFreeStmt( SQL_CLOSE
);
1458 SQLFreeStmt( SQL_UNBIND
);
1459 SQLFreeStmt( SQL_RESET_PARAMS
);
1460 if (fsqlStmt_
) fsqlStmt_
->free();
1463 isPrepared_
= false;