/******************************************************************************* ** ** Source File Name = samputil.c 1.11.2.2 ** ** Licensed Materials - Property of IBM ** ** (C) COPYRIGHT International Business Machines Corp. 1995, 1999 ** All Rights Reserved. ** ** US Government Users Restricted Rights - Use, duplication or ** disclosure restricted by GSA ADP Schedule Contract with IBM Corp. ** ** ** PURPOSE : ** ** A DB2 Version 2 sample that has been unchanged. See the CLI sample ** samputil.c for the same program updated to use the latest set ** of functions. ** ** - contains various sample functions, used by most other samples: ** - connect ** - print_connect_info ** - terminate ** - check_error ** - print_error ** - print_results ** ** For more information about these samples see the README file. ** ** For more information on programming in CLI see the: ** - "Building CLI Applications" section of the Application Building Guide, and the ** - CLI Guide and Reference. ** ** For more information on the SQL language see the SQL Reference. ** *******************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sqlcli1.h" #include "v2sutil.h" #define MAXCOLS 255 #ifndef max #define max(a,b) (a > b ? a : b) #endif /* Global Variables for user id and password, defined in main module. To keep samples simple, not a recommended practice. The INIT_UID_PWD macro is used to initialize these variables. */ extern SQLCHAR server[SQL_MAX_DSN_LENGTH + 1]; extern SQLCHAR uid[MAX_UID_LENGTH + 1]; extern SQLCHAR pwd[MAX_PWD_LENGTH + 1]; /********************************************************************/ SQLRETURN DBconnect(SQLHENV henv, SQLHDBC * hdbc) { SQLRETURN rc; SQLSMALLINT outlen; /* allocate a connection handle */ if (SQLAllocConnect(henv, hdbc) != SQL_SUCCESS) { printf(">---ERROR while allocating a connection handle-----\n"); return (SQL_ERROR); } /* Set AUTOCOMMIT OFF */ rc = SQLSetConnectOption(*hdbc, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF); if (rc != SQL_SUCCESS) { printf(">---ERROR while setting AUTOCOMMIT OFF ------------\n"); return (SQL_ERROR); } rc = SQLConnect(*hdbc, server, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS); if (rc != SQL_SUCCESS) { printf(">--- Error while connecting to database: %s -------\n", server); SQLDisconnect(*hdbc); SQLFreeConnect(*hdbc); return (SQL_ERROR); } else { /* Print Connection Information */ printf(">Connected to %s\n", server); } return (SQL_SUCCESS); } /********************************************************************/ /* DBconnect2 - Connect with conect type and syncpoint type */ /* Valid connect types SQL_CONCURRENT_TRANS, SQL_COORDINATED_TRANS */ /* Valid syncpoint types, SQL_1_PHASE, SQL_2_PHASE */ /********************************************************************/ SQLRETURN DBconnect2(SQLHENV henv, SQLHDBC * hdbc, SQLINTEGER contype, SQLINTEGER conphase) { SQLRETURN rc; SQLSMALLINT outlen; /* allocate a connection handle */ if (SQLAllocConnect(henv, hdbc) != SQL_SUCCESS) { printf(">---ERROR while allocating a connection handle-----\n"); return (SQL_ERROR); } /* Set AUTOCOMMIT OFF */ rc = SQLSetConnectOption(*hdbc, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF); if (rc != SQL_SUCCESS) { printf(">---ERROR while setting AUTOCOMMIT OFF ------------\n"); return (SQL_ERROR); } rc = SQLSetConnectOption(hdbc[0], SQL_CONNECTTYPE, contype); if (rc != SQL_SUCCESS) { printf(">---ERROR while setting Connect Type -------------\n"); return (SQL_ERROR); } if (contype == SQL_COORDINATED_TRANS ) { rc = SQLSetConnectOption(hdbc[0], SQL_SYNC_POINT, conphase); if (rc != SQL_SUCCESS) { printf(">---ERROR while setting Syncpoint Phase --------\n"); return (SQL_ERROR); } } rc = SQLConnect(*hdbc, server, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS); if (rc != SQL_SUCCESS) { printf(">--- Error while connecting to database: %s -------\n", server); SQLDisconnect(*hdbc); SQLFreeConnect(*hdbc); return (SQL_ERROR); } else { /* Print Connection Information */ printf(">Connected to %s\n", server); } return (SQL_SUCCESS); } /******************************************************************** ** Prompted_Connect - Prompt for connect options and connect ** ********************************************************************/ int Prompted_Connect(SQLHENV henv, SQLHDBC * hdbc) { SQLRETURN rc; SQLCHAR buffer[255]; SQLSMALLINT outlen; /* Set AUTOCOMMIT OFF */ rc = SQLSetConnectOption(*hdbc, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF); if (rc != SQL_SUCCESS) { printf(">---ERROR while setting AUTOCOMMIT OFF ------------\n"); return (SQL_ERROR); } printf(">Enter Server Name:\n"); gets((char *) server); printf(">Enter User Name:\n"); gets((char *) uid); printf(">Enter Password:\n"); gets((char *) pwd); rc = SQLConnect(*hdbc, server, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS); if (rc != SQL_SUCCESS) { printf(">--- ERROR while connecting to %s -------------\n", server); return (SQL_ERROR); } else { printf("Successful Connect to %s\n", server); return (SQL_SUCCESS); } } /* end Prompted_Connect */ /********************************************************************/ SQLRETURN terminate(SQLHENV henv, SQLRETURN rc) { SQLCHAR buffer[255]; SQLSMALLINT outlen; printf(">Terminating ....\n"); print_error(henv, SQL_NULL_HDBC, SQL_NULL_HENV, rc, __LINE__, __FILE__); /* Free environment handle */ if (SQLFreeEnv(henv) != SQL_SUCCESS) print_error(henv, SQL_NULL_HDBC, SQL_NULL_HENV, rc, __LINE__, __FILE__); return (rc); } /********************************************************************/ /* Print Connection Information */ SQLRETURN print_connect_info(SQLHDBC hdbc) { SQLCHAR buffer[255]; SQLSMALLINT outlen; SQLRETURN rc; printf("-------------------------------------------\n"); rc = SQLGetInfo(hdbc, SQL_DATA_SOURCE_NAME, buffer, 255, &outlen); CHECK_DBC(hdbc, rc); printf("Connected to Server: %s\n", buffer); rc = SQLGetInfo(hdbc, SQL_DATABASE_NAME, buffer, 255, &outlen); CHECK_DBC(hdbc, rc); printf(" Database Name: %s\n", buffer); rc = SQLGetInfo(hdbc, SQL_SERVER_NAME, buffer, 255, &outlen); CHECK_DBC(hdbc, rc); printf(" Instance Name: %s\n", buffer); rc = SQLGetInfo(hdbc, SQL_DBMS_NAME, buffer, 255, &outlen); CHECK_DBC(hdbc, rc); printf(" DBMS Name: %s\n", buffer); rc = SQLGetInfo(hdbc, SQL_DBMS_VER, buffer, 255, &outlen); CHECK_DBC(hdbc, rc); printf(" DBMS Version: %s\n", buffer); printf("-------------------------------------------\n"); return (rc); } /******************************************************************* ** - print_error - call SQLError(), display SQLSTATE and message ** - called by check_error, see below *******************************************************************/ SQLRETURN print_error(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN frc, /* Return code to be included with error msg */ int line, /* Used for output message, indcate where */ char * file) /* the error was reported from */ { SQLCHAR buffer[SQL_MAX_MESSAGE_LENGTH + 1]; SQLCHAR SQLSTATE[SQL_SQLSTATE_SIZE + 1]; SQLINTEGER sqlcode; SQLSMALLINT length; printf(">--- ERROR -- RC= %d Reported from %s, line %d ------------\n", frc, file, line); while (SQLError(henv, hdbc, hstmt, SQLSTATE, &sqlcode, buffer, SQL_MAX_MESSAGE_LENGTH + 1, &length) == SQL_SUCCESS) { printf(" SQLSTATE: %s\n", SQLSTATE); printf("Native Error Code: %ld\n", sqlcode); printf("%s \n", buffer); }; printf(">--------------------------------------------------\n"); return (SQL_ERROR); } /********************************************************************* * The following macros (defined in samputil.h) use check_error * * #define CHECK_ENV( henv, RC) if (RC != SQL_SUCCESS) \ * {check_error(henv, SQL_NULL_HDBC, SQL_NULL_HSTMT, RC, __LINE__, __FILE__);} * * #define CHECK_DBC( hdbc, RC) if (RC != SQL_SUCCESS) \ * {check_error(SQL_NULL_HENV, hdbc, SQL_NULL_HSTMT, RC, __LINE__, __FILE__);} * * #define CHECK_STMT( hstmt, RC) if (RC != SQL_SUCCESS) \ * {check_error(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt, RC, __LINE__, __FILE__);} * ***********************************************************************/ /******************************************************************* ** - check_error - call print_error(), checks severity of return code *******************************************************************/ SQLRETURN check_error(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN frc, int line, char * file) { SQLRETURN rc; print_error(henv, hdbc, hstmt, frc, line, file); switch (frc) { case SQL_SUCCESS: break; case SQL_INVALID_HANDLE: printf("\n>------ ERROR Invalid Handle --------------------------\n"); case SQL_ERROR: printf("\n>--- FATAL ERROR, Attempting to rollback transaction --\n"); rc = SQLTransact(henv, hdbc, SQL_ROLLBACK); if (rc != SQL_SUCCESS) printf(">Rollback Failed, Exiting application\n"); else printf(">Rollback Successful, Exiting application\n"); exit(terminate(henv, frc)); break; case SQL_SUCCESS_WITH_INFO: printf("\n> ----- Warning Message, application continuing --------\n"); break; case SQL_NO_DATA_FOUND: printf("\n> ----- No Data Found, application continuing --------- \n"); break; default: printf("\n> ----------- Invalid Return Code --------------------- \n"); printf("> --------- Attempting to rollback transaction ---------- \n"); SQLTransact(henv, hdbc, SQL_ROLLBACK); exit(terminate(henv, frc)); break; } return (SQL_SUCCESS); } /* end check_error */ SQLRETURN print_results(SQLHSTMT hstmt) { SQLCHAR colname[32]; SQLSMALLINT coltype; SQLSMALLINT colnamelen; SQLSMALLINT nullable; SQLUINTEGER collen[MAXCOLS]; SQLSMALLINT scale; SQLINTEGER outlen[MAXCOLS]; SQLCHAR *data[MAXCOLS]; SQLCHAR errmsg[256]; SQLRETURN rc; SQLSMALLINT nresultcols; int i; SQLINTEGER displaysize; rc = SQLNumResultCols(hstmt, &nresultcols); CHECK_STMT(hstmt, rc); for (i = 0; i < nresultcols; i++) { SQLDescribeCol(hstmt, i + 1, colname, sizeof(colname), &colnamelen, &coltype, &collen[i], &scale, NULL); /* get display length for column */ SQLColAttributes(hstmt, i + 1, SQL_COLUMN_DISPLAY_SIZE, NULL, 0, NULL, &displaysize); /* * set column length to max of display length, and column name * length. Plus one byte for null terminator */ collen[i] = max(displaysize, strlen((char *) colname)) + 1; printf("%-*.*s", (int)collen[i], (int)collen[i], colname); /* allocate memory to bind column */ data[i] = (SQLCHAR *) malloc((int)collen[i]); /* bind columns to program vars, converting all types to CHAR */ rc = SQLBindCol(hstmt, i + 1, SQL_C_CHAR, data[i], collen[i], &outlen[i] ); } printf("\n"); /* display result rows */ while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA_FOUND) { errmsg[0] = '\0'; for (i = 0; i < nresultcols; i++) { /* Check for NULL data */ if (outlen[i] == SQL_NULL_DATA) printf("%-*.*s", (int)collen[i], (int)collen[i], "NULL"); else { /* Build a truncation message for any columns truncated */ if (outlen[i] >= collen[i]) { sprintf((char *) errmsg + strlen((char *) errmsg), "%d chars truncated, col %d\n", (int)outlen[i] - collen[i] + 1, i + 1); } /* Print column */ printf("%-*.*s", (int)collen[i], (int)collen[i], data[i]); } } /* for all columns in this row */ printf("\n%s", errmsg); /* print any truncation messages */ } /* while rows to fetch */ /* free data buffers */ for (i = 0; i < nresultcols; i++) { free(data[i]); } return(SQL_SUCCESS); } /* end print_results */