[C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when field
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15

Thread: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when field

  1. #1
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when field

    Hey ho!

    I'm using ADO to link my WinAPI app with MS Access (SQL statements).

    All works perfectly - without any problems i can read and write to the db (although i find ADO itself a bit annoying and painful :-) )

    Anyways, there is one problem i cannot really deal with by myself anymore, when i read the fields from pField and when the particular field is empty (blank) then following throws the exception:

    pFields->GetItem(nIndex)->GetValue())

    Obviously i can somehow handle this using try / catch (_com_error & ) but i rather not do that coz i use try/catch to catch "real" errors.
    Forcing the user to always fill all fields in is also nothing i want to do coz with a massive amount of data he/she needs to enter, doing this for non mandatory fields would be very painful and simply pointless. So when i read the db and some fields are empty i just wanna get the pointer to the empty string ('\0'):


    _bstr_t jakisstring = _bstr_t(pFields->GetItem(nIndex)->GetValue());
    but as i mentioned the app immediately throws the error

    any ideas?

    I know there's been a threat for this already:
    http://forums.codeguru.com/printthread.php?t=182988
    but it does not seem it's been addressed, so here i am posting this once again myself.

    berkov
    .

  2. #2
    Join Date
    Apr 1999
    Posts
    27,423

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Quote Originally Posted by berkov View Post
    Anyways, there is one problem i cannot really deal with by myself anymore, when i read the fields from pField and when the particular field is empty (blank) then following throws the exception:

    pFields->GetItem(nIndex)->GetValue())
    The obvious suggestion to you is to break up that statement into multiple statements.

    Where do you check if pFields is valid? Where do you check if nIndex is valid? Given all that, where do you check if pFields->GetItem(nIndex) is valid? In other words, don't write code assuming that all of those items are returning valid pointers.
    Obviously i can somehow handle this using try / catch (_com_error & ) but i rather not do that coz i use try/catch to catch "real" errors
    That makes no sense whatsoever.

    When you write code that will be used by others, you never assume things just "work". You don't know the setup of the other user's computer, system, DB, etc, thus you must check for any and all errors that could occur.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; April 23rd, 2013 at 04:12 AM.

  3. #3
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,291

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Quote Originally Posted by berkov View Post
    Anyways, there is one problem i cannot really deal with by myself anymore, when i read the fields from pField and when the particular field is empty (blank) then following throws the exception:

    pFields->GetItem(nIndex)->GetValue())
    Well, what is the problem for you to check all these intermediate values to be non-NULL?
    Something like
    Code:
    if(pFields)
    {
    	FieldPtr field = pFields->GetItem(nIndex);
    	if(field)
    	{
    		_variant_t vtValue = field->GetValue();
    		...
    	}
    	else
    	{
    		... handle the case of NULL
    	}
    }
    else
    {
    	... handle the case of NULL
    }
    Quote Originally Posted by berkov View Post
    Obviously i can somehow handle this using try / catch (_com_error & ) but i rather not do that coz i use try/catch to catch "real" errors.
    Well, if you are using ADO and you want you program to run properly then you must use try / catch (_com_error & ) blocks. Period.
    Victor Nijegorodov

  4. #4
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Paul, Thanks for the reply.

    I am sure that pFields->GetItem(nIndex)->GetValue()) is correct coz actually the way I use it is to fill out the comboboxes with the specific data (passed by params to function) from db (Access) as follows:

    Code:
    void db_fill_combo (HWND control, int identifier, LPSTR columns)
    {
    
    db_connect();
    _bstr_t roww;
    _bstr_t query = "SELECT " + (_bstr_t)columns + " FROM t_param";
      
    try
    {
        recordset->Open(query, 
        _variant_t((IDispatch *) connection, true), 
        ADODB::adOpenUnspecified,
        ADODB::adLockUnspecified, 
        ADODB::adCmdText);
    }
    catch( _com_error & )
    {
        MessageBox( 0, " error handler - Blad 0219 - Blad przy uruchmieniu (IDispatch) query odczytu t_params - combo.", "Blad 0219", 0 );
       CoUninitialize();	
    }
    
    
    ADODB::Fields* pFields = NULL;
    try
    {
         recordset->get_Fields(&pFields);
    }
    catch( _com_error & )
    {
        MessageBox( 0, " error handler - Blad 0220 - Blad przy wypelnieniu struktury get_Fields z t_params - combo.", "Blad 0220", 0 );
       CoUninitialize();	
    }
    
    
    try
    {
       int rowCount = 0;
        while (!recordset->ADOEOF)
          {
             for(long nIndex=0; nIndex < pFields->GetCount() ; nIndex++)
              {
                SendDlgItemMessage(control, identifier, CB_ADDSTRING, 0, (LPARAM) (LPSTR)_bstr_t(pFields->GetItem(nIndex)->GetValue()));    
              }
             recordset->MoveNext();
            rowCount++;
          }
    }
    catch( _com_error & )
    {
         MessageBox( 0, " error handler - Blad 0221 - Blad przy nadawaniu wartosci GetItem->GetValue.", "Blad 0221", 0 );
         CoUninitialize();	
    }               
    					
    }


    So first of all this is the result of the query itself:
    A | B | C | | | X
    F | G | H | | | Y
    K | L | M | | | Z
    Meaning the first 3 cells in each row are for sure not empty.

    1st check:
    When I modify for(long nIndex=0; nIndex < pFields->GetCount() ; nIndex++)
    to: for(long nIndex=0; nIndex < 3 ; nIndex++)
    I don’t get any errors, function finishes successfully and the combobox is filled out with the following lines:
    A
    B
    C
    F
    G
    H
    K
    L
    M

    2nd check:
    I run the loop in the debug mode and I exactly know when it fails – at the empty cell after “C” so I am sure it is caused by the empty cell,.

    3rd check - When I updated the table with dummy values, it does not fail.

    Answering your other question, I don’t; want to divide it into multiple statements coz I will use this function to fill out more than one combobox with different data, multiple statements would not work in some specyfic set of input params. This is some generic function as I will have many comboboxes and wanna keep the code clear.


    Hope you will come out with something, what i am looking for is not a workaround but a permanent solution.
    There must be some way to get reed of error on GetValue() with empty blank “cell”


    btw. i don't write this code for others, i write it for myself so i want to keep it understood for myself and don't want to put more than it's necessary for me to potentially modify it in future.

    thanks for the time
    berkov
    .
    Last edited by berkov; April 23rd, 2013 at 07:18 AM. Reason: code formatting

  5. #5
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,266

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    When you post code, please format it first and use code tags (Go Advanced, selct the code then click '#').
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  6. #6
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,291

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Please, edit your post adding Code tags around your code snippet! Otherwise it is absutely unreadable!

    Quote Originally Posted by berkov View Post
    Code:
    ...
    catch( _com_error & )
    {
       MessageBox( 0, " error handler - Blad 0219 - Blad przy uruchmieniu (IDispatch) query odczytu t_params - combo.", "Blad 0219", 0 );
       CoUninitialize();	
    }
    Why do you show such a dummy message that does not give you any useful info about the cause of the exception?
    Why not use the _com_error::ErrorMessage or/and some other _com_error methods to retrieve error info?

    Not also, that there may be more different sources of errors passed via ADO. And not all of them have the descriptions returned by _com_error class. See, for instanse, how to get the provider error information.

    Also have a look at this thread.
    Victor Nijegorodov

  7. #7
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Ok.
    1. sorry guys for the code. i got used to using a different forum where only the admin had rights to format the code.
    corrected, hope it's easier to ready now.

    2. it isn't really a dummy message, it supposed to give a user something he can remember and tell me, i would then try to reproduce and if needed i would add more error catch'ers and/ or debug.

    3. why not using a different sources of errors passed? reason is simple, i cannot learn everything at once and never really had to dig in so deep to learn how it works. i know this part of coding is also very important but as long as i couldhandle it differently i decided to focuse more on "actual" code. anyway i guess, with this problem i will finally have to learn how to catch and then read the errors :-).. it might take me some time before i go thru it all, though! :-)

  8. #8
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Victor,
    your link helped:
    http://forums.codeguru.com/showthrea...an-empty-field

    i am not sure why it did not come out on my search results. anyways the code is:
    Code:
    try
    {
       int rowCount = 0;
       variant_t vtName;
       while (!recordset->ADOEOF)
        {
           for(long nIndex=0; nIndex < pFields->GetCount() ; nIndex++)
            {
              vtName = pFields->GetItem( nIndex )->GetValue();
              SendDlgItemMessage(control, identifier, CB_ADDSTRING, 0, (LPARAM) (LPSTR)_bstr_t((vtName.vt == VT_NULL) ? " " :  vtName));    
            }
          recordset->MoveNext();
          rowCount++;
        }
    }

    Thanks a lot for the help once again!

    berkov
    .

  9. #9
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,291

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Good to know you have solved your problem.
    Perhaps, you could do it earlir if you catched the exeptions! (I guess catching COleException could help you to understand that NULL and empty string are absolutely different types and it is not possible to simply convert a VARIANT containig NULL to BSTR)
    Victor Nijegorodov

  10. #10
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Cannot say anything else but just agree with you :-)

  11. #11
    Join Date
    Apr 1999
    Posts
    27,423

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Quote Originally Posted by berkov View Post
    btw. i don't write this code for others, i write it for myself so i want to keep it understood for myself and don't want to put more than it's necessary for me to potentially modify it in future.
    It really doesn't matter who the code is written for.

    You should get into the habit of writing correct, sound code. Here are the reasons:

    1) By checking for errors yourself, i.e. applying the proper try/catch blocks, calling GetLastError(), etc. you will discover the errors yourself without needing help on a programming forum.

    2) When you actually do need to write software that others will use, you will get into the habit of writing code that checks for errors, and not assume functions just work on any computer you run your program on.

    Basically this:

    If you code badly now, it is a very good chance that when you actually do need to write software for other users, it will be written badly. If you write correct code now, then it is a very good chance that when you actually do write software for other users, it will be correct.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; April 24th, 2013 at 01:32 PM.

  12. #12
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,266

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    "Bad coding habits are easy to catch and hard to shift. Good coding habits immunize against infection."
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  13. #13
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Thanks for advices...

    i'm having other problem now..
    if i fill in combo with this:
    Code:
    SendDlgItemMessage(control, identifier, CB_ADDSTRING, 0, (LPARAM) (LPSTR)_bstr_t((vtName.vt == VT_NULL) ? " " :  vtName));
    it works!

    but when i want to get it to string like this:
    Code:
    LPSTR lpstrtext = (LPSTR) _bstr_t((vtName.vt == VT_NULL) ? " " :  vtName);
    although vtName on debug shows real text, the "lpstrtext" gets freaky values like 'č' or 'î' etc...

    there seems to be some problem with conversion. any idea why?

  14. #14
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Know it now!

    Code:
    LPSTR lpstrtext = ( LPSTR ) GlobalAlloc( GPTR, sizeof(vtName.bstrVal)); 
    _bstr_t temp = vtName.bstrVal;
    strcpy (lpstrtext, temp) ;

  15. #15
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,927

    Re: [C++ ADO- SQL] pFields->GetItem (index)->GetValue () - throws an exception when f

    Code:
    #include <windows.h>
    #include <stdio.h>
    
    int main()
    {
        VARIANT vt;
    	printf("%d", sizeof(vt.bstrVal));
    	return 0;
    }
    Code:
    D:\Temp\86>cl 86.cpp
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    86.cpp
    Microsoft (R) Incremental Linker Version 10.00.40219.01
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /out:86.exe
    86.obj
    
    D:\Temp\86>86
    4
    See anything dangerous?
    Best regards,
    Igor

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center