Solved

ODBC Driver problem.. Please help me...

Posted on 1998-09-09
3
319 Views
Last Modified: 2010-04-02
Hello Experts,

I got problem with this application that are connect to ODBC drivers.I had develop a function call SearchData(ITEMCODE[]) in Visual C++ which involved accessing tables from Microsoft Access Database. And the tables each consists of 100 records. The API I used to pass parameters (ITEMCODE) to the function is develop in VB5.0. The sample code in VB is very simple as below:
   Do Until EOF()
      ITEMCODE = rc("fldItemCode")
      value = SearchData(ITEMCODE)
  Loop

The first time I run this application which loop around 100 times(100 records from same table involve in SearchData), it manage to produce the right output. But the second time, it produce junk..... When I use different computer to process this appllication, it manage to go only 2 round...and then it produce junk... When I debug thru the SearchData function, I discover that the ODBC driver were disconnected
(rc = -1). I try to assign const rc = 1(force to connect) but still the same, unless I quit application and rerun again.


The code that I used to connect ODBC driver is as below:

SQLHENV henv = NULL;
SQLHDBC hdbc = NULL;
SQLHSTMT hstmt = NULL;
SQLRETURN rc;

if (SQL_SUCCESS ==
   (rc = ::SQLAllocHandle(SQL_HANDLE_ENV,
   SQL_NULL_HANDLE, &henv)))
      {
     if (SQL_SUCCESS == (rc = ::SQLSetEnvAttr(henv,
         SQL_ATTR_ODBC_VERSION,(SQLPOINTER)
         SQL_OV_ODBC3, SQL_IS_INTEGER)))
            {
             if (SQL_SUCCESS == (rc =                     ::SQLAllocHandle(SQL_HANDLE_DBC, henv,                     &hdbc)))
            {
               rc = ::SQLConnect(hdbc, (SQLCHAR*)"Bank                         Negara Formula Database", SQL_NTS,
                  (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"",                          SQL_NTS);
               if ((SQL_SUCCESS == rc)
                  || (SQL_SUCCESS_WITH_INFO == rc))
               {
                  bIsConnected = 'T';
                  if (SQL_SUCCESS == (rc                        = ::SQLAllocHandle(SQL_HANDLE_STMT,
                  hdbc, &hstmt)))
                  {
                                                strcpy(statement,"SELECT fldTag FROM tblItemCode ");
      strcat(statement, "where flditemcode = ");
      strcat(statement,"'");
      strcat(statement, ITEMCODE);
      strcat(statement,"'");
      LPCSTR szSQL = statement;

      if (SQL_SUCCESS == (rc = ::SQLPrepare(hstmt,
      (unsigned char*)szSQL, SQL_NTS)))
      {
      if (SQL_SUCCESS == (rc = ::SQLExecute(hstmt)))
      {
        SDWORD cb;
          char szItmTag[LEN_TAG];
        SQLBindCol(hstmt, 1, SQL_C_CHAR, szItmTag,
            LEN_TAG, &cb);
         rc = SQLFetch(hstmt);
          ITEMCODE[LEN_ITEMCODE]='\0';
            if (rc == SQL_SUCCESS)
            {
            while (SQL_SUCCESS == rc)
            {
            strcpy(itmtag, szItmTag);
            rc = SQLFetch(hstmt);
            } // end while SQL_SUCCESS
          }

Can some expert help me in or show me the better way of connecting to ODBC driver. I really appreciate it. Thank you.
0
Comment
Question by:dekoay
  • 2
3 Comments
 

Accepted Solution

by:
bobbym earned 50 total points
ID: 1172323
I think the problem with this function is that is does not free the handles it gets from the ODBC driver (this by the way also explains why the functions runs and then suddenly stops). To correct the problem you must free all the handles that you use using SQLFreeHandle passing the function the handle and the appropriate type of the handle. Please note that you must free the handles in a reverse order e.g. the last allocated gets freed first!

It is also preferable to keep a global copy of the connection and environment handles for performance reasons if you use this functions often, because the ODBC driver will not have to do the additional work of creating a connection and environment.

An easier for sure method is to use some library implementation for working with ODBC (like MFC) and leave the dirty work.

I hope this helped :).

 

0
 

Author Comment

by:dekoay
ID: 1172324
Hello Bobbyn,

Yes, i did free all handle that I created, it just i diddn't show them here becoz the program is very long. However, a new discoveries has occur after i made some modification to the stack I created. This time it loops until 5 times before it return me a junk value. Now, I suspected that it causes by memory problem. Is there a way I can destroy the stack I created after used ?

Thank You, Bob. Yur help is truly appreciated.

Regards
Dekoay
0
 

Expert Comment

by:bobbym
ID: 1172325
Dear Dekoay,
I'm not quite sure that I'm getting the idea (about the stack), but the problem is obviously connected with the handles (since you have to re-run the program to make it run again.
I see that you are using a lot ot strcat, strcpy and so on. I think it's a good idea to check wheather those functions do not mess the memory, especially if for example the statement and itmtag variables are declared before the handles. Make sure you do not overwrite the memory for the handles, cause as I can see they are declared after those two and so reside after them in the stack.
Can you move for example all the handles above in the stack and try to increase the size of the string variables. If you get  more rows without junk maybe that is the problem :) (maybe not) :)

Best regards Bob
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now