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
Solved

Database connection VS .NET / SQL Server

Posted on 2003-12-12
8
608 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
  • 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
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
VB.NET how to use the Vertical ScrollBar 5 114
windows 10 how make picture as desktop background 2 65
substring method in java 1 129
format the code in java 6 101
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
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.

856 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