Solved

Database connection VS .NET / SQL Server

Posted on 2003-12-12
8
613 Views
Last Modified: 2013-11-20
I am trying out to create a database connected application using MS Visual Studio .NET.
I create a new project (MDI) and says that it should have database access.. I enter the name of the ODBC DNS and the database which
it should connect to and then create the project.. (ODBC DNS works perfectly - I can use it in Borland environment without problems).
Visula STudio creates the project and when running it with F5 it displays the default resource dialog form.. The problems occurs when I try to interact with the record set.
I put a CEDIT control on the form which I name IDC_EDIT_USERTYPE and my intention is to show the usertype field in that control.
In the view-class in the 'DoDataExchange(CDataExchange* pDX)' method I am according to the remarks able to connect the variables from the record set to a control so I write the line:
' DDX_FieldText(pDX, IDC_EDIT_USERTYPE, (CString) m_pSet->m_user_type, m_pSet); (m_user_type is the variable which the record connects to that specific field in the recordset.

Ok, I run the app with F5 and this is where my two problems occur.

1: Almost every time I start the app for the first time I get a timeout error. The database is on (local) machine and I am connected to it through SQL server, so I know it's up. I also get this error sometimes after running the app a while.
2: The CEdit field displays a correct value from one row of the database. When I use "Next Record" in the toolbar I get an Assertion Error in dbcore.cpp in the method "void CRecordset::SetFieldNull(void* pv, BOOL bNull)"
The call that creates the assertion failure is:
      
      // If no field found, m_nFieldFound will still be zero
      ASSERT(fx.m_nFieldFound != 0);

When I ignore the assertion or debug it but then continue, I get the next value in the correct CEDIT field, but every time I choose "Next record" I get the assertion failure, so I have to (in debug mode) choose ignore every single time..

Why? :)

dbcore.cpp is a system file and the only things I've added to the standard project created by Visual Studio are the CEdit control and the line in DoDataExchange..

0
Comment
Question by:Trickster
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
8 Comments
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 9927536
DoFieldExchange() doesn't find a BOOL field of your record set and tells you by a DEBUG Assertion.

Normally, you have entries like

        RFX_Text(pFX, "Name", m_strName);
        RFX_Bool(pFX, "DoILikeHer", m_bLikeHer);

in Wizard-generated code. However, one of these names couldn't be found in a RFX_Bool line.
Maybe there is a problem with case-sensitivity.

You should set a breakpoint to the line with the DoFieldExchange() call in dbcore.cpp and check the fx.m_pstr Parameter for the name of the required fields.

Regards, Alex  
0
 

Author Comment

by:Trickster
ID: 9927727
Hmm.. If I set a break at dbcore.cpp at the assertion failure and trace back through the call stack it's the DDX_FieldText(pDX, IDC_EDIT1, (CString) m_pSet->m_user_type, m_pSet); method that calls it. (In ConnectView::DoDataExchange(CDataExchange* pDX))

This is the only call I have in the DDoDataExchange method except for the initial CRecordView::DoDataExchange(pDX); method..  

In the DoFieldExchange method I only have 2 different bool fields and after removing both I still get the same error...

// T
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 9928205
It's the DoFieldExchange() method that should have the correct field names. If you remove them, no fields are found and you will get more assertions. You may set a break point to the first RFX_...  line of DoFieldExchange() . Then by stepping into the functions you will see the name required and perhaps you will find the missing or misspelled field name.

Could you give us the all table column names as shown by a database tool and the code of the DoFieldExchange() method?

Regards, Alex

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 9928232
Don't forget the data types and SQL types of your fields. In SQL Server there is a NCHAR type that is a multibyte type and that isn't compatible to CRecordSet.
0
 

Author Comment

by:Trickster
ID: 9928322
Sure, but I can't find any differences in spelling or in case-sensitivity :-(  I only ask for 6 values, and here they are:

SQL Server:
Name:           Type:             Length:            Allows Null
---------------------------------------------------------------------
user_id          nvarchar         20                   No
amount_left    money            8                    Yes
user_type       nvarchar         15                  No
date_created  datetime         8                    No
logged_on       bit                 1                    No
free_time        int                 4                    Yes

void CSidewalkDBConnectSet::DoFieldExchange(CFieldExchange* pFX)
{
      pFX->SetFieldType(CFieldExchange::outputColumn);
// Macros such as RFX_Text() and RFX_Int() are dependent on the
// type of the member variable, not the type of the field in the database.
// ODBC will try to automatically convert the column value to the requested type
      RFX_Text(pFX, _T("[user_id]"), m_user_id);
      RFX_Double(pFX, _T("[amount_left]"), m_amount_left);
      RFX_Text(pFX, _T("[user_type]"), m_user_type);
      RFX_Date(pFX, _T("[date_created]"), m_date_created);
      RFX_Bool(pFX, _T("[logged_on]"), m_logged_on);
      RFX_Long(pFX, _T("[free_time]"), m_free_time);
}

And also for reference, the DoDataExchange method:

void CSidewalkDBConnectView::DoDataExchange(CDataExchange* pDX)
{
      CRecordView::DoDataExchange(pDX);
      // you can insert DDX_Field* functions here to 'connect' your controls to the database fields, ex.
      // DDX_FieldText(pDX, IDC_MYEDITBOX, m_pSet->m_szColumn1, m_pSet);
      // DDX_FieldCheck(pDX, IDC_MYCHECKBOX, m_pSet->m_bColumn2, m_pSet);
      // See MSDN and ODBC samples for more information

      DDX_FieldText(pDX, IDC_EDIT_USERTYPE, (CString) m_pSet->m_user_type, m_pSet);
}
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 125 total points
ID: 9928477
Some comments:

1. I would say that you have to remove the bracket characters [] of the RFX_... lines, because
    DoFieldExchange compares the field names of the data source to these names.

2. I had problems with the nvarchar type because it is UNICODE, i. e. 2 bytes per character  - as far
    i know. The _T macro will handle this - i suppose - but only if you have defined the UNICODE
    macro with your project settings.

3. The macros to connect controls to database fields must be defined in DoDataExchange()
    (most lines are commented  in your code). However, the third argument must be a CString,
    double, int, BYTE, ... , but not a char pointer or char array as m_szColumn1 looks like.
    I don't know what m_user_type is, but it should be a l-value CString and not only be casted
    to be one.

Hope, that helps

Alex
0
 

Author Comment

by:Trickster
ID: 9928658
Ahh.. Hmm.. In the declaration for the variables the wizard had chosen unicode CStringW for declaration of nvarchar variables - that's why I had a cast to (CString) in the DoDataExchange. When I let the ODBC driver convert it by declaring the var to CString instead and removing the cast it worked!!

Strange, but I am happy! :)

Thanks for the help

// T
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 9928691
One more comment:

CRecordSet uses ODBC to connect to your SQL Server Database. So, yo easily may change the database engine to MS ACCESS, ORACLE, DB2, MYSQL, and others. However, this only works if a you avoid to use non-compatible data types.

In your example above, the only data type i would recommend is 'int'. All others will not work on some of engines mentioned above. I have made a big system where i used only one type, VARCHAR, that is (almost) compatible to all systems, and it was a good decision because i never had problems with that.

So i would recommend NOT to use

- money     (if you are lucky it will be converted to double elsewhere, but the precision will be
                  different from system to system)
- datetime  (that is a really mess, because nearly none is compatible to any other. If you take
                   a string and store date-time in YYYYMMDDhhmmss you will be happy)
- bit           (take an int - 1/0 - or string - 'T'/'F')

Regards, Alex

0

Featured Post

Get MongoDB database support online, now!

At Percona’s web store you can order your MongoDB database support needs in minutes. No hassles, no fuss, just pick and click. Pay online with a credit card. Handle your MongoDB database support now!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …

630 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