Database Forum / DB2 Topics / February 2006
Urgent issue!!! Embedded SQL & CLI connection sharing c/c++.
|
|
Thread rating:  |
Marco - 08 Feb 2006 18:30 GMT Hi,
I'm facing a bit puzzeling problem. I need to check the connection status in an embedded SQL application, and my idea was adding a CLI call: SQLGetConnectAttr().I'm using it in many CLI programs and everything's fine.
Now comes the problem: if I've issued the connection via EXEC SQL CONNECT therefore I do not have any valid connection handle!!!
The DB2 manual is quite unclear: "... or it performs all connects and commits/rollbacks using embedded SQL, and then calls functions that use DB2 CLI APIs, notably, a null connection."
What is a null connection?
I've tried in many ways but I cannot even allocate a connection handle (only the environment seems to work). I'm getting an invalid connection handle while allocating the connection handle, even if the allocation of the environment handle was fine...
I'm really in big troubles!
Thank you very much in advance.
Knut Stolze - 09 Feb 2006 10:33 GMT > Hi, > [quoted text clipped - 12 lines] > > What is a null connection? A NULL connection is a connection established without a database name and without any user credentials (user name + password).
Here is a short example demonstrating how to mix embedded SQL & CLI in the way you want: -------------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <sqlca.h> #include <sqlcli.h>
int main() { SQLRETURN rc = 0; SQLHENV envHandle = SQL_NULL_HANDLE; SQLHDBC dbcHandle = SQL_NULL_HANDLE; SQLHSTMT stmtHandle = SQL_NULL_HANDLE;
EXEC SQL INCLUDE SQLCA;
EXEC SQL CONNECT TO TEST; if (SQLCODE) { printf("Connect failed. rc = %d\n", (int)SQLCODE); return EXIT_FAILURE; }
// get env & dbc handle rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &envHandle); if (rc != 0) { printf("Alloc environment handle rc = %d\n", (int)rc); goto cleanup; } rc = SQLAllocHandle(SQL_HANDLE_DBC, envHandle, &dbcHandle); if (rc != 0) { printf("Alloc connection handle rc = %d\n", (int)rc); goto cleanup; }
// establish "null connection", i.e. derive the CLI connection from // the connection established with embedded SQL before rc = SQLConnect(dbcHandle, NULL, 0, NULL, 0, NULL , 0); if (rc != 0) { printf("CLI connect rc = %d\n", (int)rc); goto cleanup; }
// execute some statement in CLI rc = SQLAllocHandle(SQL_HANDLE_STMT, dbcHandle, &stmtHandle); if (rc != 0) { printf("Alloc statement handle rc = %d\n", (int)rc); goto cleanup; } rc = SQLExecDirect(stmtHandle, "CREATE TABLE x ( a INT )", SQL_NTS); if (rc != 0) { printf("CREATE TABLE rc = %d\n", (int)rc); goto cleanup; }
EXEC SQL COMMIT WORK;
cleanup: // cleanup must be done here
EXEC SQL CONNECT RESET;
return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } --------------------------------------------------------------------
> I've tried in many ways but I cannot even allocate a connection handle > (only the environment seems to work). I'm getting an invalid connection > handle while allocating the connection handle, even if the allocation > of the environment handle was fine... You don't allocate a connection handle by providing a connection handle. The dbc handle is allocated off the env handle.
 Signature Knut Stolze DB2 Information Integration Development IBM Germany
Marco - 09 Feb 2006 12:52 GMT Thanks a lot Knut,
I've just solved it a few minutes ago, the way you suggested, but the manual does not explain what a NULL connection is, in the chapter about CLI & EMBEDDED SQL. I've found it under the SQLConnect(), about the storedp procedure NULL connect, and your sample is not availabe in the official docuentation, I guess.
Regards.
Knut Stolze - 09 Feb 2006 16:38 GMT > I've just solved it a few minutes ago, the way you suggested, but the > manual does not explain what a NULL connection is, in the chapter about > CLI & EMBEDDED SQL. > I've found it under the SQLConnect(), about the storedp procedure NULL > connect, and your sample is not availabe in the official docuentation, > I guess. No, it's not. :-( The documentation contains a lot of info and one should always have a look there. But there are always things that could be improved.
 Signature Knut Stolze DB2 Information Integration Development IBM Germany
Marco - 09 Feb 2006 17:10 GMT Hi Knut,
I've found something quite strange: everything was fine, as I've told you, but the SQLGetConnectAttr(), using SQL_ATTR_CONNECTION_DEAD, returns always an SQL_SUCCESS with connection status "0", that means "not dead", alive, even if the connection has been killed from CLP. It does not return SQL_SUCCESS only if the network cable has been unplugged, but than the connection status is not relevant.
That's what I've found somewhere on the net:
http://search.cpan.org/src/IBMTORDB2/DBD-DB2-0.78/dbdimp.c
I don't really know where this dbdimp.c module is coming from (there's an IBM copyright), but as you can see, it states that the SQL_ATTR_CONNECTION_DEAD attribute is not reliable (why???), and it suggests a workaround, quite easy, that uses a SQLPrepare() or EXEC SQL PREPARE, and check the state. I've applied the concept in my source code and everything is working fine.
I apologize with you, but when I'm reading messages like "read the documentation" I'm getting always a bit upset. I'm always dooing it, and I've used DB2 for something like 10 years, but I'm still finding that the documentation is not as clear as it should be, even when the issue is not really that new.
Thanks a lot for your help. Regards.
Serge Rielau - 09 Feb 2006 18:09 GMT > Hi Knut, > [quoted text clipped - 25 lines] > Thanks a lot for your help. > Regards. Did you "kill" with quit, terminate or connect reset? Note that quit does NOT reset the connection.
Cheers Serge
 Signature Serge Rielau DB2 Solutions Development DB2 UDB for Linux, Unix, Windows IBM Toronto Lab
Knut Stolze - 09 Feb 2006 18:12 GMT > I've found something quite strange: everything was fine, as I've told > you, but the SQLGetConnectAttr(), using SQL_ATTR_CONNECTION_DEAD, > returns always an SQL_SUCCESS with connection status "0", that means > "not dead", alive, even if the connection has been killed from CLP. The return code of SQLGetConnectAttr() is showing you if the function call succeeded. It does not say anything about the attribute value that you want to retrieve. So if you say "returns SQL_SUCCESS", I assume that you are referring to the return code of the function. Instead you should check the value stored by DB2 in the "valuePtr" and for SQL_ATTR_CONNECTION_DEAD this value is either one of the following two (and not SQL_SUCCESS):
* SQL_CD_FALSE - the connection is still active. * SQL_CD_TRUE - an error has already happened and caused the connection to the server to be terminated. The application should still perform a disconnect to clean up any DB2 CLI resources.
(http://publib.boulder.ibm.com/infocenter/db2luw/v8//topic/com.ibm.db2.udb.doc/ad /r0006816.htm)
I think that the connection attribute works just a bit different than what you need. It gives you SQL_CD_TRUE only if an error _already_ happened. I agree, using a ping or something like that would be a better solution.
 Signature Knut Stolze DB2 Information Integration Development IBM Germany
Marco - 10 Feb 2006 08:10 GMT Hi Knut,
I'm sorry but I'm sure I did not explain myself that much. I know that the return code of the CLI API(s) is showing the function call status only, and not the connection one (or whatever the API is used to), but I'm testing both:
1) in case the cable is unplugged the return code is -1 (SQL_ERROR), and I do not test the valuePr. 2) in case of forced disconnection (CLP), the function return SQL_SUCCESS, but the valuePtr is always "false", that means "still active".
I was not able, in my test environment, the retrieve a "true" valuePtr, while "pinging" seems to work fine.
Do you have an idea about it? And do you know where the c module I've found is coming from?
To Serge: I'm killing the connection from CLP or from Control Center, specifing the "FORCE" option.
Thanks to all of you. Regards.
Knut Stolze - 10 Feb 2006 08:18 GMT > I was not able, in my test environment, the retrieve a "true" valuePtr, > while "pinging" seems to work fine. For me, the value you got is "true". The documentation states (as I quoted) that SQL_CD_TRUE is returned if an error _already_ occured before. So if the connection terminates at a point in time where nothing is going on, there is nothing in the CLI logic that will notice it (naturally). And if the very first thing after the termination is the test whether it is dead, DB2 correctly returns the information from the last work and that is SQL_CD_FALSE. Retrieving the attribute value itself does not cause the connection to be actively used. Therefore, it "works as designed".
If you ping the server, you force some work to be done that needs the connection channel.
> Do you have an idea about it? And do you know where the c module I've > found is coming from? This looks like some PHP or Perl code to me. I don't know for sure.
 Signature Knut Stolze DB2 Information Integration Development IBM Germany
Marco - 10 Feb 2006 08:30 GMT Thanks a lot Knut,
I didn't understand it that way. I thought the CLI was performing a kind of dummy action itself, before returning the valuePtr. So, standing at facts, it does nothing but test the sql state after a previously performed function!
Thanks again, Regards.
|
|
|