But for some reason the execution stops at SQLExecDirect. No line is written in the dump file and ret value cannot be accessed. I am connecting to an Oracle DB from an application than runs in Windows 2008 R2. I dont really know how I can debug this further.
Re: Issue when using SQLExecDirect against Oracle DSN
Originally Posted by joseoliv
Hi all,
Im having an issue when executing SQLExecDirect function in the code below:
Why are you casting to unsigned char* in the SQLExecDirect?
That is a red flag right there. If you casted because you wanted to keep the compiler from telling you there is an error or warning, then that whole call is suspicious.
The reason why is that functions that take or return pointers to string data require you to ensure that the string data you pass is compatible. If you compiled with Unicode, and that function expects a Unicode string, then what you did is totally incorrect.
1) What is the actual prototype to SQLExecDirect? What are the actual parameter types for each argument?
2) What build type are you using, ANSI or Unicode?
3) You have "outstr" in your previous calls. What exactly is "outstr"? This is another red flag. If the build is UNICODE and that is a char array, then again, your code is using incompatible string types if the ODBC call expects wide strings (and returns wide strings).
Regards,
Paul McKenzie
Last edited by Paul McKenzie; June 20th, 2012 at 03:49 AM.
I quite new at VS2010 and I just noticed that CharacterSet is not set to any value for the Project im working at. How this could affect the execution of the statement?
Re: Issue when using SQLExecDirect against Oracle DSN
Originally Posted by joseoliv
Hi Paul,
Thanks very much for your response. I actually copied one of the "bad" tries I did. Here is the code I am currently working at:
I still don't see what the definition of outstr is iin all of that code.
Also, the question was simple, but you didn't answer -- what is the prototype to SQLExecDirect. What are the exact parameter types expected?
I quite new at VS2010 and I just noticed that CharacterSet is not set to any value for the Project im working at. How this could affect the execution of the statement?
It will effect everything if those ODBC calls are sensitive to string types. That entire code block would need to be rewritten. If you don't believe me, set the character set to Unicode and have fun fixing all the compiler errors.
Once the SQL is executed I just need to save the content of the unique column retrieved (DISTINCT LOGIN) into a const char* variable. So I think the scope of the function is pretty simple.
I did some tests with Unicode charset and got some errors in SQLCHAR->SQLWCHAR. After redefining those variable I could compile with no issues. But the result is still bad, the dll crashes at SQLExecDirect.....
Re: Issue when using SQLExecDirect against Oracle DSN
Originally Posted by joseoliv
Hi Paul,
I did some tests with Unicode charset and got some errors in SQLCHAR->SQLWCHAR. After redefining those variables I could compile with no issues.
First, can you format the code a little better, i.e. less cramped and better indented? It is hard to read your code.
Here is the problem:
Code:
std::string select = "SELECT DISTINCT LOGIN FROM SIEBUTV2.S_USER WHERE LOGIN_DOMAIN ='" + u + "'";
If you really did compile with Unicode, then that line is wrong. The std::string works only with 8-bit character strings. The correct string type if the compile is Unicode is std::wstring, not std::string.
This is incorrect, as the type is probably SQLTCHAR, not SQLCHAR. Secondly, Unicode strings are 16-bit chars. This means that using sizeof() is totally wrong. The correct way to state this is:
Code:
sizeof(outstr) / sizeof(outstr[0])
That code determines the number of characters (again, since characters are 16-bit in Unicode, not 8 bit).
Here is the overall problem -- you're string types are screwed up. You are assuming things are 8-bit when they could be 16-bit, and you're using hard-coded char arrays instead of build-neutral string types.
Start slowly, and recode that entire function using string types that are neutral to whatever build you're using. This means usage of TCHAR, usage of the _T() macros to specify string literals, using SQLTCHAR instead of specifically stating SQLCHAR or SQLWCHAR, using the correct functions or code snippets to get the number of characters in an array, etc.
In other words, if that code is using char, char*, std::string in any way, it's wrong, even if it compiles. If you do that, then regardless of the build type, the code would work.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; June 20th, 2012 at 05:09 AM.
What is the reason to declare a pointer, when the array itself can be used?
Then you do this:
Code:
ret = SQLExecDirect(stmt, sql, strlen((char *)sql));
The strlen() function works on NULL terminated strings. There is no guarantee that sqlstmt is NULL terminated. That last parameter could be 0, or 234432, 56, or any integer you can think of.
Second, what does the third parameter denote? Is it a length()? Or does it mean something else?
But all of this is a moot point -- the probable reason your code crashes is a basic mishandling and misunderstanding of string data in the C++ language, and string handling for ANSI/Unicode Windows apps in general.
Everything seems fine connecting to the source and allocating the sql statement, but again I cannot go thru the SQLExecDirect statement. I dont know exactly what is going wrong, can you see something "suspicious" within the ODBC Connection function SQLDriverConnect that might affect the execution of the SQL?
Re: Issue when using SQLExecDirect against Oracle DSN
First of all, are you able to get any (non-void) resultset for the query using the credentials user/pwd in any other tool, e.g. sqlplus console?
Second, what is behind SQL_SUCCEEDED? Are you sure SQL_SUCCESS_WITH_INFO is not considered an error? What is ret value?
Third, in case ret really is SQL_ERROR, you need to call SqlGetDiagRec to find out the real reason of the failure. Which processing you obviously miss in your code. BTW, that way you could obtain not only ODBC layer error status but as well an Oracle native error code that could clue you up about what exactly happens there with your query.
Re: Issue when using SQLExecDirect against Oracle DSN
Originally Posted by joseoliv
but again I cannot go thru the SQLExecDirect statement.
Is the issue still a crash, or is it that SQLExecDirect gets called and returns a value for ret?
If it no longer crashes, then Igor is right in that you do not check further for the SQL diagnostic messages, which will tell you why the call returned with a non-success code. If you planned to run your application on other machines besides the one you're running on, then it's imperative you have full error checking, as you don't know what those other machines may have running or what ODBC version of the driver they're using.
Besides, you don't check at all for the return values for SQLAllocHandle, SQLSetEnvAttr, etc. All of these functions return values that you should be checking for, otherwise you will have an app that assumes these functions just "work", when they could also report a failure.
If on the other hand SQLExecDirect does crash, you should put together a complete but small "Hello World" type program (not a function, an entire program). Then you take that program to Oracle for them to resolve. The program shouldn't do anything else except 4 or 5 lines of calls to ODBC.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; June 25th, 2012 at 10:25 AM.
Bookmarks