/***************************************************************************/ /* */ /* (c) Copyright IBM Corp.2002 All rights reserved. */ /* */ /* This sample program is owned by International Business Machines */ /* Corporation or one of its subsidiaries ("IBM") and is copyrighted */ /* and licensed, not sold. */ /* */ /* You may copy, modify, and distribute this sample program in any */ /* form without payment to IBM, for any purpose including developing, */ /* using, marketing or distributing programs that include or are */ /* derivative works of the sample program. */ /* */ /* The sample program is provided to you on an "AS IS" basis, without */ /* warranty of any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL WARRANTIES, */ /* EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* Some jurisdictions do not allow for the exclusion or limitation of */ /* implied warranties, so the above limitations or exclusions may not */ /* apply to you. IBM shall not be liable for any damages you suffer as */ /* a result of using, modifying or distributing the sample program or */ /* its derivatives. */ /* */ /* Each copy of any portion of this sample program or any derivative */ /* work, must include the above copyright notice and disclaimer of */ /* warranty. */ /* */ /***************************************************************************/ /* The following CLI sample demonstrates using WebSphere MQ as an XA */ /* Resource coordinator with DB2 UDB Version 7.2 and has been tested using */ /* DB2 UDB Version 7.2 FP7 with MQSeries for Windows 2000 Version 5.2 */ /* service level U200148 (CSD03). */ /* */ /* This sample requires include files from both MQSeries and DB2 UDB */ /* and requires linking utilcli.obj (from DB2 UDB) and linking in both */ /* db2cli.lib and mqm.lib. */ /* */ /* Once built, this application can be executed against the SAMPLE */ /* database after the following updates have been made to db2cli.ini */ /* */ /* [SAMPLE] */ /* DBALIAS=SAMPLE */ /* CURSORHOLD=0 */ /* SYNCPOINT=2 */ /* CONNECTTYPE=2 */ /* AUTOCOMMIT=0 */ /* */ /* To run this sample, issue the following command: */ /* */ /* mqadhoc SYSTEM.DEFAULT.LOCAL.QUEUE */ /* */ /* For additional information on the necessary configuration changes to */ /* WebSphere MQ, refer to the System Administration Guide. */ /* */ /***************************************************************************/ #include #include #include #include /* DB2 include file */ #include /* MQSeries include file */ #include "utilcli.h" /* DB2 include file */ #define MAX_STMT_LEN 255 #define MAXCOLS 100 #ifndef max #define max(a,b) (a > b ? a : b) #endif /* * Global Variables for user id and password. * To keep samples simple, not a recommended practice. */ extern SQLCHAR server[SQL_MAX_DSN_LENGTH + 1] ; extern SQLCHAR uid[MAX_UID_LENGTH + 1] ; extern SQLCHAR pwd[MAX_PWD_LENGTH + 1] ; /* Function declarations: */ int process_stmt( SQLHANDLE, SQLCHAR * ) ; /******************************************************************* ** main ** - initialize ** - start a transaction ** - get statement ** - another statement? ** - COMMIT or ROLLBACK ** - another transaction? ** - terminate *******************************************************************/ int main( int argc, char * argv[] ) { FILE *fp; SQLHANDLE henv, hdbc, hstmt ; SQLCHAR sqlstmt[MAX_STMT_LEN + 1] = ""; SQLCHAR sqltrans[sizeof("ROLLBACK")]; SQLRETURN rc; MQOD od = {MQOD_DEFAULT}; /* Object Descriptor for reply */ MQMD md = {MQMD_DEFAULT}; /* Message Descriptor */ MQPMO pmo = {MQPMO_DEFAULT}; /* put message options */ MQBO bo = {MQBO_DEFAULT}; /* begin options */ MQHCONN Hcon; /* connection handle */ MQHOBJ Hobj; /* object handle, server queue */ MQLONG O_options; /* MQOPEN options */ MQLONG C_options; /* MQCLOSE options */ MQLONG OpenCode; /* completion code */ MQLONG CompCode; /* completion code */ MQLONG Reason; /* reason code */ MQLONG CReason; /* reason code (MQCONN) */ MQLONG BackCode; /* Completion code for MQBACK */ MQLONG CmitCode; /* Completion code for MQCMIT */ MQLONG BackReason; /* reason code for MQBACK */ MQLONG CmitReason; /* reason code for MQCMIT */ MQLONG BeginCode; /* completion code for MQBEGIN */ MQLONG BeginReason; /* reason code for MQBEGIN */ MQBYTE buffer[256]; /* message buffer */ MQLONG buflen; /* buffer length */ char QMName[50]; /* queue manager name */ printf("Sample mqadhoc start\n"); if (argc < 2) { printf("Missing parameter - logging queue\n"); exit(99); } /***************************************************/ /* Connect to the Queue Manager that will be used. */ /***************************************************/ QMName[0] = 0; /* default */ if (argc > 2) { strcpy(QMName, argv[2]); } MQCONN(QMName, &Hcon, &CompCode, &CReason); /* report reason and stop if it failed */ if (CompCode == MQCC_FAILED) { printf("MQCONN ended with reason code %ld\n", CReason); exit(CReason); } /******************************************************************/ /* Use first parameter as the name of the logging queue */ /******************************************************************/ strncpy(od.ObjectName, argv[1], (size_t)MQ_Q_NAME_LENGTH); printf("Logging queue is %s\n", od.ObjectName); /******************************************************************/ /* Open the target message queue for output */ /******************************************************************/ O_options = MQOO_OUTPUT + MQOO_FAIL_IF_QUIESCING; MQOPEN(Hcon, &od, O_options, &Hobj, &OpenCode, &Reason); /**********************************************/ /* report reason, if any; stop if failed */ /**********************************************/ if (Reason != MQRC_NONE) { printf("MQOPEN ended with reason code %ld\n", Reason); } if (OpenCode == MQCC_FAILED) { printf("unable to open queue for output\n"); } fp = stdin; CompCode = OpenCode; while (CompCode != MQCC_FAILED) { MQBEGIN(Hcon, &bo, &BeginCode, &BeginReason); if (BeginCode != MQCC_OK) { printf("MQBEGIN failed: Code = %ld, Reason = %ld\n", BeginCode, BeginReason); CompCode = BeginCode; } else { /**********************************/ /* allocate an environment handle */ /**********************************/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; HANDLE_CHECK( SQL_HANDLE_ENV, henv, rc, &henv, &hdbc ) ; /******************************************************/ /* Allocate a connect handle, and connect. */ /* The userid and password are not specified since MQ */ /* already connected to the DB with the MQBEGIN. */ /******************************************************/ rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; HANDLE_CHECK( SQL_HANDLE_ENV, henv, rc, &henv, &hdbc ) ; rc = SQLConnect( hdbc, "SAMPLE", SQL_NTS, (SQLCHAR *)NULL, SQL_NTS, (SQLCHAR *)NULL, SQL_NTS ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; /***************************************************/ /* allocate statement handle and process statement */ /***************************************************/ rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; HANDLE_CHECK( SQL_HANDLE_STMT, henv, rc, &henv, &hdbc ) ; printf("Enter SQL command to process:\n"); if (fgets(buffer, sizeof(buffer), fp) != NULL) { buflen = strlen(buffer); if (buffer[buflen-1] == '\n') { buffer[buflen-1] = '\0'; --buflen; } } else { buflen = 0; } if (buflen > 0) { strcpy((char *)sqlstmt, buffer); if ( process_stmt( hstmt, sqlstmt ) == SQL_ERROR ) { CompCode = MQCC_FAILED; } else { memcpy(md.Format, MQFMT_STRING, (size_t)MQ_FORMAT_LENGTH); memcpy(md.MsgId, MQMI_NONE, sizeof(md.MsgId) ); memcpy(md.CorrelId, MQCI_NONE, sizeof(md.CorrelId) ); pmo.Options = MQPMO_SYNCPOINT; MQPUT(Hcon, Hobj, &md, &pmo, buflen, buffer, &CompCode, &Reason); /*******************************************************/ /* See if the MQPUT worked. If it failed, notify the */ /* user and set the transaction to be rolled back. If */ /* worked, ask user whether to commit or roll back. */ /*******************************************************/ if (CompCode != MQCC_OK) { printf("MQPUT failed: Code = %ld, Reason = %ld\n", CompCode, Reason); strcpy(buffer, "r"); } else { printf("Enter 'c' to COMMIT or 'r' to ROLLBACK the transaction\n"); if (fgets(buffer, sizeof(buffer), fp) != NULL) { buflen = strlen(buffer); if (buffer[buflen-1] == '\n') { buffer[buflen-1] = '\0'; --buflen; } } } /*************************************************/ /* See if the user said to commit or roll back */ /* the transaction and make appropriate MQ call. */ /*************************************************/ if ((strcmp(buffer, "C") == 0) || (strcmp(buffer, "c") == 0)) { printf("Changes would be committed...\n"); MQCMIT(Hcon, &CmitCode, &CmitReason); if (CmitReason != MQRC_NONE) { printf("MQCMIT ended with reason code %ld\n", CmitReason); } } else { printf("Changes would be rolled back...\n"); MQBACK(Hcon, &BackCode, &BackReason); if (BackReason != MQRC_NONE) { printf("MQBACK ended with reason code %ld\n", BackReason); } } } } else { CompCode = MQCC_FAILED; } /********************************************/ /* Free statement handle */ /********************************************/ rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; HANDLE_CHECK( SQL_HANDLE_STMT, hdbc, rc, &henv, &hdbc ) ; /***********************************************/ /* Disconnect from database and release handle */ /***********************************************/ rc = SQLDisconnect( hdbc ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; rc = SQLFreeHandle( SQL_HANDLE_DBC, hdbc ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; /**********************************************/ /* Free environment handle */ /**********************************************/ rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; ENV_HANDLE_CHECK( henv, rc ) ; } } /* end while */ if (OpenCode != MQCC_FAILED) { C_options = 0; MQCLOSE(Hcon, &Hobj, C_options, &CompCode, &Reason); /* report reason, if any */ if (Reason != MQRC_NONE) { printf("MQCLOSE ended with reason code %ld\n", Reason); } } /****************************************************************/ /* Disconnect from the Queue Manager if not already connected. */ /****************************************************************/ if (CReason != MQRC_ALREADY_CONNECTED) { MQDISC(&Hcon, &CompCode, &Reason); /* report reason, if any */ if (Reason != MQRC_NONE) { printf("MQDISC ended with reason code %ld\n", Reason); } } return( SQL_SUCCESS ) ; } /* end main */ /*--> SQLL1X63.SCRIPT */ /******************************************************************* ** process_stmt ** - allocates a statement resources ** - executes the statement ** - determines the type of statement ** - if there are no result columns, therefore non-select statement ** - if rowcount > 0, assume statement was UPDATE, INSERT, DELETE ** else ** - assume a DDL, or Grant/Revoke statement ** else ** - must be a select statement. ** - display results ** - frees the statement resources *******************************************************************/ int process_stmt( SQLHANDLE hstmt, SQLCHAR * sqlstr ) { SQLSMALLINT nresultcols; SQLINTEGER rowcount; SQLRETURN rc; /* execute the SQL statement in "sqlstr" */ rc = SQLExecDirect(hstmt, sqlstr, SQL_NTS); if (rc != SQL_SUCCESS) if (rc == SQL_NO_DATA_FOUND) { printf("\nStatement executed without error, however,\n"); printf("no data was found or modified\n"); return (SQL_SUCCESS); } else /*indicate an error executing the statement*/ STMT_HANDLE_CHECK( hstmt, rc); /* printf("Error issuing SQLExecDirect %i",rc) ; */ rc = SQLNumResultCols(hstmt, &nresultcols); STMT_HANDLE_CHECK( hstmt, rc); /* determine statement type */ if (nresultcols == 0) { /* statement is not a select statement */ rc = SQLRowCount(hstmt, &rowcount); if (rowcount > 0) /* assume statement is UPDATE, INSERT, DELETE */ printf("Statement executed, %ld rows affected\n", rowcount); else /* assume statement is GRANT, REVOKE or a DLL statement */ printf( "Statement completed successful\n" ) ; } else StmtResultPrint( hstmt ) ; /* display the result set */ /* end determine statement type */ /* free statement resources */ rc = SQLFreeStmt( hstmt, SQL_UNBIND ) ; STMT_HANDLE_CHECK( hstmt, rc); rc = SQLFreeStmt( hstmt, SQL_RESET_PARAMS ) ; rc = SQLFreeStmt( hstmt, SQL_CLOSE ) ; return( 0 ) ; } /* end process_stmt */ /*<-- */