tags:

views:

294

answers:

2

I'm having a problem with the call to SQLGetDiagRec. It works fine in ascii mode, but in unicode it causes our app to crash, and i just can't see why. All the documentation i've been able to find seems to indicate that it should handle the ascii/unicode switch internally. The code i'm using is:

void clImportODBCFileTask::get_sqlErrorInfo( const SQLSMALLINT _htype, const SQLHANDLE _hndle )
{
SQLTCHAR      SqlState[6];
SQLTCHAR   Msg[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER    NativeError;
SQLSMALLINT   i, MsgLen;
SQLRETURN     nRet;

memset ( SqlState, 0, sizeof(SqlState) );
memset ( Msg, 0, sizeof(Msg) );

// Get the status records.
i = 1;

//JC - 2009/01/16 - Start fix for bug #26878
m_oszerrorInfo.Empty();

nRet = SQLGetDiagRec(_htype, _hndle, i, SqlState, &NativeError, Msg, sizeof(Msg), &MsgLen);
m_oszerrorInfo = Msg;
}

everything is alright until this function tries to return, then the app crashes. It never gets back to the line of code after the call to get_sqlErrorInfo.

I know that's where the problem is because i've put diagnostics code in and it gets past the SQLGetDiagRec okay and it fnishes this function.

If i comment the SQLGetDiagRec line it works fine.

It always works fine on my development box whether or not it's running release or debug.

Any help on this problem would be greatly appreciated. Thanks

A: 

A copuple of possible problems. First, when you say:

m_oszerrorInfo = Msg;

what is the type of m_oszerrorInfo? If it is a pointer, you are storing a pointer to a local variable (Msg). If you use that pointer later, Msg will no longer exist.

Secondly, names that begin with an underscore are rerved for the compiler at namespace scope. In order not to have to worry about what this means, don't use names that begin with underscores.

anon
Hi Neil, I didn't really understand this sentence: "Secondly, names that begin with an underscore are rerved for the compiler at namespace scope."Could you please explain that better? I'm curious
Edison Gustavo Muenz
Thanks for your answer. I'm pretty sure that m_oszerrorInfo isn't he problem as the problem occurs even without that line and it isn't a pointer. I only included it to show that we are doing something with the data returned. I'll try removing the _names, that's a developer we used to have that always did that and we couldn't convince him not to.
John C
@john - The underscore names will not be the problem, but they are bad practice.
anon
anon
@Neil thanks for the clarification!
Edison Gustavo Muenz
+1  A: 

Well i found the correct answer, so I thought i would include it here for future reference. The documentation i saw was wrong. SQLGetDiagRec doesn't handle Unicode i needed to use SQLGetDiagRecW.

John C
You could have compiled the project with _UNICODE and UNICODE defined, that would have mapped SQLGetDiagRec to SQLGetDiagRecW. In Visual Studio the easiest way to do this is to go to your project's properties General->Character Set = Use Unicode Character set.
Erik E
I do see in the windows code that it looks like it shoudl map, however it was crashing until i exlicitly did: #ifdef _UNICODE nRet = SQLGetDiagRecW(_htype, _hndle, i, SqlState, #else nRet = SQLGetDiagRec(_htype, _hndle, i, SqlState, #endifWe definitely do have both _UNICODE and UNICODE defined and the character set is set to the Unicode character set, but apparently for some reason the mapping wasn't working.
John C