/***** C source file name: sqlxspexample.c *****/ #define SQL_TEXT Latin_Text #include <sqltypes_td.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <coptypes.h> #include <coperr.h> #include <parcel.h> #include <dbcarea.h> #include <dbchqep.h> typedef struct { Word StatementNo; Word Info; Word Code; Word Length; char Msg[1]; /* 1 to 255 bytes */ } PclErrorFailBody, *PclErrorFailBody_pt; struct DBCAREA DBCArea; char * pContext; DBCAREA *pDBCArea; DBCAREAX *pDbcAreaX; /****************************************************************** Initialize() Initialize DBCAREA. ******************************************************************/ Int32 Initialize() { Int32 Result; pDBCArea = &DBCArea; pDBCArea->total_len = sizeof(struct DBCAREA); DBCHINI(&Result, pContext, &DBCArea); pDBCArea->change_opts = 'Y' ; pDBCArea->req_buf_len = 1024; pDBCArea->resp_buf_len = 1024; pDBCArea->use_presence_bits = 'N' ; pDBCArea->keep_resp = 'N' ; pDBCArea->loc_mode = 'Y' ; pDBCArea->var_len_req = 'N' ; pDBCArea->save_resp_buf = 'N' ; pDBCArea->two_resp_bufs = 'N' ; pDBCArea->ret_time = 'N' ; pDBCArea->wait_for_resp = 'Y' ; pDBCArea->req_proc_opt = 'E' ; pDBCArea->maximum_parcel = 'H'; pDBCArea->resp_mode = 'I'; pDBCArea->dynamic_result_sets_allowed = 'Y'; return Result; } /****************************************************************** Logon() Establish a default connection. ******************************************************************/ Int32 Logon(char *LogonStr) { Int32 Result; pDBCArea->func=DBFCON; if (LogonStr == NULL) { pDBCArea->create_default_connection = 'Y'; } else { pDBCArea->logon_len = (Int32) strlen(LogonStr); pDBCArea->logon_ptr = LogonStr; } DBCHCL(&Result, pContext, pDBCArea); if (Result != EM_OK) return Result; /* Fetch the response */ pDBCArea->i_sess_id = pDBCArea->o_sess_id; pDBCArea->i_req_id = pDBCArea->o_req_id; pDBCArea->func = DBFFET; DBCHCL(&Result,pContext,pDBCArea); if (Result != EM_OK) return Result; if ( pDBCArea->fet_parcel_flavor != PclSUCCESS ) { if ( pDBCArea->fet_parcel_flavor == PclFAILURE || pDBCArea->fet_parcel_flavor == PclERROR ) { return pDBCArea->fet_parcel_flavor; } } /* End the logon request */ pDBCArea->i_sess_id = pDBCArea->o_sess_id; pDBCArea->i_req_id = pDBCArea->o_req_id; pDBCArea->func = DBFERQ; DBCHCL(&Result, pContext, pDBCArea); return Result; } /****************************************************************** Logoff() Disconnect. ******************************************************************/ Int32 Logoff() { Int32 Result; pDBCArea->func = DBFDSC; DBCHCL(&Result, pContext, pDBCArea); return Result; } /****************************************************************** Execute() Execute the specified request. ******************************************************************/ Int32 Execute(char *ReqStr) { Int32 Result; /* Issue the request */ pDBCArea->func = DBFIRQ; pDBCArea->change_opts = 'Y'; pDBCArea->req_ptr = ReqStr; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); DBCHCL(&Result, pContext, pDBCArea); if (Result != EM_OK) return Result; /* Fetch the result parcels */ pDBCArea->func = DBFFET; pDBCArea->change_opts = 'Y'; pDBCArea->i_req_id = pDBCArea->o_req_id; while (Result == EM_OK) DBCHCL(&Result, pContext, pDBCArea); /* End the request */ pDBCArea->func = DBFERQ; DBCHCL(&Result, pContext, pDBCArea); return Result; } /****************************************************************** DoTheWork() Create the tables, call the stored procedure. ******************************************************************/ void DoTheWork() { Int32 Result; Int32 a; Int32 CallReqNo; Int32 Flavor; char ReqStr[255]; Int32* pInt32; char* pChar; /* Create a trace table */ Result = Execute("DROP TABLE TraceTable;"); if (Result != EM_OK) return; Result = Execute("CREATE TABLE TraceTable(SeqNo INT GENERATED BY DEFAULT AS IDENTITY, Flavor INT, Text VARCHAR(100));"); if (Result != EM_OK) return; /* Create a table to insert and select rows */ Result = Execute("DROP TABLE tab1;"); if (Result != EM_OK) return; Result = Execute("CREATE TABLE tab1(a INT, b INT);"); if (Result != EM_OK) return; /* Insert the rows */ for (a=1;a<=10;a++) { pDBCArea->using_data_ptr = (char *) &a; pDBCArea->using_data_len = sizeof(a); Result = Execute("USING(a INT) INSERT tab1(:a, :a);"); if (Result != EM_OK) return; } /* Call a procedure which will return a result set */ pDBCArea->func = DBFIRQ; pDBCArea->change_opts = 'Y'; pDBCArea->req_ptr = "CALL p1('SEL * FROM tab1 ORDER BY 1');"; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); DBCHCL(&Result, pContext, pDBCArea); if (Result != EM_OK) return; /* Remember the request number */ CallReqNo = pDBCArea->o_req_id; /* Fetch the result parcels and insert into the trace table */ while (Result == EM_OK) { /* Fetch a parcel from the CALL */ pDBCArea->func = DBFFET; pDBCArea->change_opts = 'Y'; pDBCArea->i_req_id = CallReqNo; DBCHCL(&Result, pContext, pDBCArea); if (Result != EM_OK) return; Flavor = pDBCArea->fet_parcel_flavor; /* Put this parcel into the trace table */ pDBCArea->func = DBFIRQ; pDBCArea->change_opts = 'Y'; pDBCArea->using_data_ptr = (char *) &Flavor; pDBCArea->using_data_len = sizeof(Flavor); if (pDBCArea->fet_parcel_flavor == PclSUCCESS) { pDBCArea->req_ptr = "USING (a INT) INSERT tracetable(,:a,'Success')"; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); } else if (pDBCArea->fet_parcel_flavor == PclDATAINFO) { pDBCArea->req_ptr = "USING (a INT) INSERT tracetable(,:a,'DataInfo')"; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); } else if (pDBCArea->fet_parcel_flavor == PclXDIX) { pDBCArea->req_ptr = "USING (a INT) INSERT tracetable(,:a,'DataInfoX')"; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); } else if (pDBCArea->fet_parcel_flavor == PclRECORD) { /* Point to the integer in the record parcel, */ /* skip past the indicator byte */ pChar = pDBCArea->fet_data_ptr; pChar++; pInt32 = (Int32 *) pChar; sprintf(ReqStr, "USING (a INT) INSERT tracetable(,:a,'Record %d ')", *pInt32); pDBCArea->req_ptr = ReqStr; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); } else if (pDBCArea->fet_parcel_flavor == PclENDSTATEMENT) { pDBCArea->req_ptr = "USING (a INT) INSERT tracetable(,:a,'EndStatement')"; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); } else if (pDBCArea->fet_parcel_flavor == PclENDREQUEST) { pDBCArea->req_ptr = "USING (a INT) INSERT tracetable(,:a,'EndRequest')"; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); } else if (pDBCArea->fet_parcel_flavor == PclRESULTSET) { pDBCArea->req_ptr = "USING (a INT) INSERT tracetable(,:a,'ResultSet')"; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); } else if (pDBCArea->fet_parcel_flavor == PclFAILURE) { pChar = pDBCArea->fet_data_ptr; pChar += 4; pInt32 = (Int32 *) pChar; pChar += 4; for(a=0;a<strlen(pChar);a++) if(pChar[a]==0x27) pChar[a]=' '; sprintf(ReqStr, "USING (a INT) INSERT tracetable(,:a,'Failure %d %s')", (*pInt32)&0x0000ffff, pChar); pDBCArea->req_ptr = ReqStr; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); } else { pDBCArea->req_ptr = "USING (a INT) INSERT tracetable(,:a,'')"; pDBCArea->req_len = (Int32) strlen(pDBCArea->req_ptr); } DBCHCL(&Result, pContext, pDBCArea); if (Result != EM_OK) return; /* Fetch the success etc from the insert into the trace table */ pDBCArea->func = DBFFET; pDBCArea->change_opts = 'Y'; pDBCArea->i_req_id = pDBCArea->o_req_id; while (Result == EM_OK) DBCHCL(&Result, pContext, pDBCArea); /* End the insert request */ pDBCArea->func = DBFERQ; DBCHCL(&Result, pContext, pDBCArea); /* Go and fetch the next parcel from the CALL */ } } /****************************************************************** Entry point for the external stored procedure. ******************************************************************/ void sqlxspex( char sqlstate[6], SQL_TEXT extname[129], SQL_TEXT specific_name[129], SQL_TEXT error_message[257]) { Initialize(); Logon(NULL); DoTheWork(); Logoff(); }