/******************************************************************************* ** ** Source File Name = spserver.c ** ** Licensed Materials - Property of IBM ** ** (C) COPYRIGHT International Business Machines Corp. 2000 ** All Rights Reserved. ** ** US Government Users Restricted Rights - Use, duplication or ** disclosure restricted by GSA ADP Schedule Contract with IBM Corp. ** ** ** PURPOSE : This program demonstrates stored procedures implemented in CLI. ** ** There are two parts to this program: ** - the spclient executable (placed on the client) ** - the spserver library (placed on the server) ** ** BUILDING THE SHARED LIBRARY: ** 1. Ensure the Database Manager Configuration file has the keyword KEEPDARI ** set to "no". This allows unloading shared libraries while developing stored ** procedures. You can view the file's settings by entering the command: ** "db2 get dbm cfg". You can set KEEPDARI to "no" with this command: ** "db2 update dbm cfg using KEEPDARI no". ** NOTE: Setting KEEPDARI to "no" causes a performance cost when accessing the stored ** procedures because they have to be reloaded into memory each time they are called. ** If this is a consideration, use the KEEPDARI "yes" setting, and stop and restart ** DB2 before building the shared library, by entering "db2stop" followed by "db2start". ** This forces DB2 to unload shared libraries and enables the build file or the makefile ** to delete a previous version of the shared library from the "function" directory. ** 2. To build the shared library, enter "bldclisp spserver" (UNIX & OS/2), "make ** spserver" (UNIX), "nmake spserver" (OS/2 & Windows), or for the Microsoft Visual ** C++ compiler on Windows, enter "bldmclis spserver", or for the VisualAge C++ compiler ** on Windows, enter "bldvclis spserver". ** 3. To catalog the stored procedures in the shared library, first connect to the ** database by entering: "db2 connect to sample". ** 4. If the stored procedures were previously cataloged for a different language, ** uncatalog them by entering: "db2 -td@ -vf spdrop.db2". ** 5. Then, catalog the stored procedures by entering: "db2 -td@ -vf spcreate.db2". ** ** 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. ** *******************************************************************************/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sqlcli1.h> #include <sqlca.h> #include <sqludf.h> #include "utilcli.h" /* Declare structure for VARCHAR type */ struct small_varchar { sqlint16 length; char data[12]; }; /* Declare function prototypes for this stored procedure library */ SQL_API_RC SQL_API_FN outlanguage (char *); SQL_API_RC SQL_API_FN out_param (double *, sqlint32 *, char *); SQL_API_RC SQL_API_FN in_params (double *, double *, double *, char *, sqlint32 *, char *); SQL_API_RC SQL_API_FN inout_param (double *inoutMedian, sqlint32 *, char *, sqlint16 *); SQL_API_RC SQL_API_FN one_result_set_to_caller (double *, sqlint32 *); SQL_API_RC SQL_API_FN two_result_sets (double *, sqlint32 *); SQL_API_RC SQL_API_FN extract_from_clob (char *, char *, sqlint32 * ); SQL_API_RC SQL_API_FN all_data_types (sqlint16 *, sqlint32 *, sqlint64 *, float *, double *, char *, char *, struct small_varchar *, char *, char *, sqlint32 *, char *); SQL_API_RC SQL_API_FN db2sql_example(char *, double *, sqlint16 *, char *, char *, char *, char *); SQL_API_RC SQL_API_FN dbinfo_example (char *, double *, char *, char *, sqlint32 *, struct sqludf_dbinfo *); SQL_API_RC SQL_API_FN main_example (int, char **); SQL_API_RC SQL_API_FN outlanguage (char out_lang[9]) { SQLHANDLE henv, hdbc, hstmt ; SQLRETURN rc,rc1 ; SQLCHAR stmt[100]; sqlint32 indicator; /*-----------------------------------------------------------------*/ /* Setup CLI required environment */ /*-----------------------------------------------------------------*/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); /*-----------------------------------------------------------------*/ /* Issue NULL Connect, since in CLI we need a statement handle */ /* and thus a connection handle and environment handle. */ /* A connection is not established, rather the current */ /* connection from the calling application is used */ /*-----------------------------------------------------------------*/ SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ; SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; strcpy((char*)stmt,"SELECT LANGUAGE FROM sysibm.sysprocedures "); strcat((char*)stmt,"WHERE procname = 'OUT_LANGUAGE' "); rc = SQLExecDirect( hstmt, stmt, SQL_NTS ) ; /* bind columns to variables */ rc = SQLBindCol( hstmt, 1, SQL_C_CHAR, out_lang, 9, &indicator); STMT_HANDLE_CHECK( hstmt, rc); /* fetch each row, and display */ rc = SQLFetch( hstmt ); STMT_HANDLE_CHECK( hstmt, rc); if(rc != SQL_SUCCESS) return (0); rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; 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 ) ; rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; return (0); } /* end outlanguage function */ char buffer[33]; SQL_API_RC SQL_API_FN out_param(double *outMedianSalary, sqlint32 *out_sqlcode, char buffer[33]) { sqlint16 num_records; double medianSalary; int counter = 0; SQLHANDLE henv, hdbc, hstmt ; SQLHANDLE hstmt1 ; SQLRETURN rc, rc1 ; SQLCHAR stmt[100]; SQLCHAR stmt1[100]; sqlint32 indicator; struct sqlca sqlca; /*-----------------------------------------------------------------*/ /* Setup CLI required environment */ /*-----------------------------------------------------------------*/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); /*-----------------------------------------------------------------*/ /* Issue NULL Connect, since in CLI we need a statement handle */ /* and thus a connection handle and environment handle. */ /* A connection is not established, rather the current */ /* connection from the calling application is used */ /*-----------------------------------------------------------------*/ SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ; rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt1 ) ; if ( rc != SQL_SUCCESS ) return (0); strcpy((char*)stmt,"SELECT CAST(salary AS DOUBLE) FROM staff "); strcat((char*)stmt,"order by salary"); strcpy((char*)stmt1,"SELECT count(*) FROM staff "); rc = SQLExecDirect( hstmt1, stmt1, SQL_NTS) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecDirect( hstmt, stmt, SQL_NTS) ; if ( rc != SQL_SUCCESS ) return (0); strcpy(buffer, "SQLExec"); /* bind columns to variables */ rc = SQLBindCol( hstmt1, 1, SQL_C_SHORT, &num_records , 0, NULL); if ( rc != SQL_SUCCESS ) return (0); rc = SQLBindCol( hstmt, 1, SQL_C_DOUBLE, &medianSalary , 0, &indicator); if ( rc != SQL_SUCCESS ) return (0); /* fetch rowno. */ rc = SQLFetch( hstmt1 ); if( rc != SQL_SUCCESS || rc == SQL_NO_DATA_FOUND) { rc1 = SQLGetSQLCA(henv, hdbc, hstmt1, &sqlca); *out_sqlcode = SQLCODE; return (0); } /* while (counter < (num_records / 2 + 1)) { */ for(counter=0; rc == SQL_SUCCESS && counter < (num_records/2+1); counter++) rc = SQLFetch( hstmt ); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; strcpy(buffer, "FETCH"); /* Set value of OUT parameter to host variable */ *outMedianSalary = medianSalary; rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt1 ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; 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 ) ; rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; return (0); } /* end out_param function */ char department[4]; SQL_API_RC SQL_API_FN in_params (double *inlowsal, double *inmedsal, double *inhighsal, char department[4], sqlint32 *out_sqlcode, char buffer[33]) { double lowsal; double medsal; double highsal; double salary; double tmp; SQLHANDLE henv, hdbc, hstmt ; SQLHANDLE hstmt1 ; SQLRETURN rc,rc1 ; SQLCHAR stmt[100]; SQLCHAR stmt1[100]; sqlint32 indicator; struct sqlca sqlca; SQLCHAR cursor[20]; SQLSMALLINT clength ; lowsal = *inlowsal; medsal = *inmedsal; highsal = *inhighsal; /*-----------------------------------------------------------------*/ /* Setup CLI required environment */ /*-----------------------------------------------------------------*/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); /*-----------------------------------------------------------------*/ /* Issue NULL Connect, since in CLI we need a statement handle */ /* and thus a connection handle and environment handle. */ /* A connection is not established, rather the current */ /* connection from the calling application is used */ /*-----------------------------------------------------------------*/ SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ; rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt1 ) ; if ( rc != SQL_SUCCESS ) return (0); /* set AUTOCOMMIT off or on */ rc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, SQL_NTS) ; strcpy((char*)stmt,"SELECT CAST(salary AS DOUBLE) FROM EMPLOYEE "); strcat((char*)stmt,"WHERE workdept = ? FOR UPDATE OF salary"); rc = SQLPrepare(hstmt, stmt, SQL_NTS); if ( rc != SQL_SUCCESS ) return (0); /* Bind the parameter to application variables () */ rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,0, 0, department, 4, NULL); if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecute(hstmt); /* bind columns to variables */ rc = SQLBindCol( hstmt, 1, SQL_C_DOUBLE, &salary , 0, &indicator); if ( rc != SQL_SUCCESS ) return (0); /* Get Cursor of the SELECT statement's handle */ rc = SQLGetCursorName( hstmt, cursor, 20, &clength ) ; if ( rc != SQL_SUCCESS ) return (0); sprintf((char *)stmt1, "UPDATE EMPLOYEE set salary = ? where current of %s ", cursor); rc = SQLPrepare(hstmt1, stmt1, SQL_NTS); if ( rc != SQL_SUCCESS ) return (0); /* fetch rowno. */ rc = SQLFetch( hstmt ); strcpy(buffer, "FETCH (1)"); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; if ( rc != SQL_SUCCESS ) return (0); while( rc == SQL_SUCCESS) { if (salary < lowsal) { rc = SQLBindParameter(hstmt1, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,0, 0, &lowsal, 0, NULL); rc = SQLExecute(hstmt1); strcpy(buffer, "UPDATE (1)"); if ( rc != SQL_SUCCESS ) return (0); } else if (salary < medsal ) { rc = SQLBindParameter(hstmt1, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,0, 0, &medsal, 0, NULL); rc = SQLExecute(hstmt1); strcpy(buffer, "UPDATE (2)"); if ( rc != SQL_SUCCESS ) return (0); } else if (salary < highsal ) { rc = SQLBindParameter(hstmt1, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,0, 0, &highsal, 0, NULL); rc = SQLExecute(hstmt1); strcpy(buffer, "UPDATE (3)"); if ( rc != SQL_SUCCESS ) return (0); } else { tmp=salary*1.1; rc = SQLBindParameter(hstmt1, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,0, 0, &tmp, 0, NULL); rc = SQLExecute(hstmt1); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; strcpy(buffer, "UPDATE (4)"); if ( rc != SQL_SUCCESS ) return (0); } rc = SQLFetch( hstmt ); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; strcpy(buffer, "FETCH (2)"); if ( rc == SQL_ERROR ) return (0); } if(SQLCODE == 100) *out_sqlcode =0; strcpy(buffer, "RETURN 1"); rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt1 ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; 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 ) ; rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; return (0); } /* end in_params function */ SQL_API_RC SQL_API_FN inout_param (double *inoutMedian, sqlint32 *out_sqlcode, char buffer[33], sqlint16 nullinds[3]) { sqlint16 num_records; double medianSalary; double tmpsalary; int counter = 0; SQLHANDLE henv, hdbc, hstmt ; SQLHANDLE hstmt1 ; SQLRETURN rc,rc1 ; SQLCHAR stmt[100]; SQLCHAR stmt1[100]; sqlint32 indicator; struct sqlca sqlca; medianSalary = *inoutMedian; /*-----------------------------------------------------------------*/ /* Setup CLI required environment */ /*-----------------------------------------------------------------*/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); /*-----------------------------------------------------------------*/ /* Issue NULL Connect, since in CLI we need a statement handle */ /* and thus a connection handle and environment handle. */ /* A connection is not established, rather the current */ /* connection from the calling application is used */ /*-----------------------------------------------------------------*/ SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ; if (nullinds[0] < 0) { /* NULL value was received as input, so return NULL output */ nullinds[0] = -1; nullinds[1] = -1; nullinds[2] = -1; return 0; } rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt1 ) ; if ( rc != SQL_SUCCESS ) return (0); strcpy((char*)stmt,"SELECT CAST(salary AS DOUBLE) FROM staff "); strcat((char*)stmt,"where salary > ? order by salary "); strcpy((char*)stmt1,"SELECT count(*) FROM staff "); strcat((char*)stmt1,"WHERE salary > ? "); rc = SQLPrepare(hstmt, stmt, SQL_NTS); if ( rc != SQL_SUCCESS ) return (0); rc = SQLPrepare(hstmt1, stmt1, SQL_NTS); if ( rc != SQL_SUCCESS ) return (0); /* Bind the parameter to application variables () */ rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,0, 0, &medianSalary, 0, NULL); if ( rc != SQL_SUCCESS ) return (0); rc = SQLBindParameter(hstmt1, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,0, 0, &medianSalary, 0, NULL); if ( rc != SQL_SUCCESS ) return (0); strcpy(buffer, "inout_param"); rc = SQLExecute(hstmt); if ( rc != SQL_SUCCESS ) return (0); /* bind columns to variables */ rc = SQLBindCol( hstmt, 1, SQL_C_DOUBLE, &tmpsalary , 0, &indicator); if ( rc != SQL_SUCCESS ) return (0); rc = SQLBindCol( hstmt1, 1, SQL_C_SHORT, &num_records, 0,&indicator); if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecute(hstmt1); if ( rc != SQL_SUCCESS ) { rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; return (0); } /* fetch rowno. */ rc = SQLFetch( hstmt1 ); strcpy(buffer, "SQLExec"); for(counter=0; rc == SQL_SUCCESS && counter < (num_records/2+1); counter++) { rc = SQLFetch( hstmt ); } /* Set value of INOUT parameter to median salary */ rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *inoutMedian = tmpsalary; *out_sqlcode = SQLCODE; strcpy(buffer, "FETCH "); if ( rc != SQL_SUCCESS ) return (0); rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt1 ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; 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 ) ; rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; return (0); } /* end inout_param function */ double l_insalary; SQL_API_RC SQL_API_FN one_result_set_to_caller (double *insalary, sqlint32 *out_sqlcode) { double medianSalary; int counter = 0; SQLHANDLE henv, hdbc, hstmt ; SQLRETURN rc,rc1 ; SQLCHAR stmt[100]; struct sqlca sqlca; l_insalary = *insalary; /*-----------------------------------------------------------------*/ /* Setup CLI required environment */ /*-----------------------------------------------------------------*/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); /*-----------------------------------------------------------------*/ /* Issue NULL Connect, since in CLI we need a statement handle */ /* and thus a connection handle and environment handle. */ /* A connection is not established, rather the current */ /* connection from the calling application is used */ /*-----------------------------------------------------------------*/ SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ; rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; if ( rc != SQL_SUCCESS ) return (0); strcpy((char*)stmt,"SELECT name, job, CAST(salary AS DOUBLE) AS salary"); strcat((char*)stmt," FROM staff WHERE salary > ? ORDER BY salary"); rc = SQLPrepare(hstmt, stmt, SQL_NTS); if ( rc != SQL_SUCCESS ) return (0); /* Bind the parameter to application variables () */ rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,0, 0, &l_insalary, 0, NULL); if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecute(hstmt); if ( rc != SQL_SUCCESS ) return (0); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; /* test fetch */ rc = SQLFetch( hstmt ); if ( rc != SQL_SUCCESS ) return (0); if (rc == SQL_ERROR) { rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; } rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; rc = SQLDisconnect( hdbc ) ; rc = SQLFreeHandle( SQL_HANDLE_DBC, hdbc ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; return (0); } /* end one_result_set_to_caller function */ SQL_API_RC SQL_API_FN two_result_sets (double *inMedianSalary, sqlint32 *out_sqlcode) { SQLHANDLE henv, hdbc, hstmt ; SQLHANDLE hstmt1,hstmt2 ; SQLRETURN rc,rc1 ; SQLCHAR stmt[100]; SQLCHAR stmt1[150]; struct sqlca sqlca; /*-----------------------------------------------------------------*/ /* Setup CLI required environment */ /*-----------------------------------------------------------------*/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); /*-----------------------------------------------------------------*/ /* Issue NULL Connect, since in CLI we need a statement handle */ /* and thus a connection handle and environment handle. */ /* A connection is not established, rather the current */ /* connection from the calling application is used */ /*-----------------------------------------------------------------*/ SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ; rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt1 ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt2 ) ; if ( rc != SQL_SUCCESS ) return (0); /* Statement for first result set: staff with a salary greater than the IN parameter */ strcpy((char*)stmt,"SELECT name, job, CAST(salary AS DOUBLE) AS salary"); strcat((char*)stmt," FROM staff WHERE salary > ? ORDER BY salary"); /* Statement for first result set: staff with a salary less than the IN parameter */ strcpy((char*)stmt1,"SELECT name, job, CAST(salary AS DOUBLE) AS salary"); strcat((char*)stmt1," FROM staff WHERE salary < ? "); strcat((char*)stmt1,"ORDER BY salary DESC"); rc = SQLPrepare(hstmt, stmt, SQL_NTS); if ( rc != SQL_SUCCESS ) return (0); rc = SQLPrepare(hstmt1, stmt1, SQL_NTS); if ( rc != SQL_SUCCESS ) return (0); /* Bind the parameter to application variables () */ rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,0, 0, inMedianSalary, 0, NULL); if ( rc != SQL_SUCCESS ) return (0); rc = SQLBindParameter(hstmt1, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,0, 0, inMedianSalary, 0, NULL); if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecute(hstmt); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecute(hstmt1); rc1 = SQLGetSQLCA(henv, hdbc, hstmt1, &sqlca); *out_sqlcode = SQLCODE; return (0); } /* end two_result_sets function */ SQL_API_RC SQL_API_FN all_data_types (sqlint16 *smallInOut, sqlint32 *intInOut, sqlint64 *bigInOut, float *realInOut, double *doubleInOut, char charOut[2], char charsOut[16], struct small_varchar *varcharOut, char dateOut[11], char timeOut[9], sqlint32 *out_sqlcode, char buffer[33]) { SQLHANDLE henv, hdbc, hstmt ; SQLHANDLE hstmt1, hstmt2, hstmt3, hstmt4; SQLCHAR stmt[100]; SQLCHAR stmt1[100]; SQLCHAR stmt2[100]; char firstnme[13]; /* VARCHAR(12) */ SQLRETURN rc,rc1 ; sqlint32 indicator; struct sqlca sqlca; if (*smallInOut == 0) { *smallInOut = 1; } else { *smallInOut = (*smallInOut / 2); } if (*intInOut == 0) { *intInOut = 1; } else { *intInOut = (*intInOut / 2); } if (*bigInOut == 0) { *bigInOut = 1; } else { *bigInOut = (*bigInOut / 2); } if (*realInOut == 0) { *realInOut = 1; } else { *realInOut = (*realInOut / 2); } if (*doubleInOut == 0) { *doubleInOut = 1; } else { *doubleInOut = (*doubleInOut / 2); } /*-----------------------------------------------------------------*/ /* Setup CLI required environment */ /*-----------------------------------------------------------------*/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); /*-----------------------------------------------------------------*/ /* Issue NULL Connect, since in CLI we need a statement handle */ /* and thus a connection handle and environment handle. */ /* A connection is not established, rather the current */ /* connection from the calling application is used */ /*-----------------------------------------------------------------*/ SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ; rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt1 ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt2 ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt3 ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt4 ) ; if ( rc != SQL_SUCCESS ) return (0); strcpy((char*)stmt,"SELECT midinit from employee "); strcat((char*)stmt,"WHERE empno = '000180'"); strcpy((char*)stmt1,"SELECT lastname from employee "); strcat((char*)stmt1,"WHERE empno = '000180'"); strcpy((char*)stmt2,"SELECT firstnme from employee "); strcat((char*)stmt2,"WHERE empno = '000180'"); rc = SQLExecDirect( hstmt, stmt, SQL_NTS) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecDirect( hstmt1, stmt1, SQL_NTS) ; if ( rc != SQL_SUCCESS ) return (0); strcpy(buffer, "SQLExec"); /* bind columns to variables */ rc = SQLBindCol( hstmt, 1, SQL_C_CHAR, charOut , 2, &indicator); if ( rc != SQL_SUCCESS ) return (0); rc = SQLBindCol( hstmt1, 1, SQL_C_CHAR, charsOut , 16, &indicator); if ( rc != SQL_SUCCESS ) return (0); rc = SQLFetch( hstmt ); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; strcpy(buffer, "SELECT midinit"); if ( rc != SQL_SUCCESS ) return (0); rc = SQLFetch( hstmt1 ); rc1 = SQLGetSQLCA(henv, hdbc, hstmt1, &sqlca); *out_sqlcode = SQLCODE; strcpy(buffer, "SELECT LASTNAME"); if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecDirect( hstmt2, stmt2, SQL_NTS) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLBindCol( hstmt2, 1, SQL_C_CHAR, firstnme, 13, &indicator); if ( rc != SQL_SUCCESS ) return (0); rc = SQLFetch( hstmt2 ); rc1 = SQLGetSQLCA(henv, hdbc, hstmt2, &sqlca); *out_sqlcode = SQLCODE; strcpy(buffer, "SELECT FIRSTNAME"); if ( rc != SQL_SUCCESS ) return (0); /* Set the length field of the VARCHAR struct */ varcharOut->length = strlen(firstnme); /* Copy the data from firstnme into the data field of the VARCHAR struct */ memcpy(varcharOut->data, (char *)firstnme, varcharOut->length); strcpy((char*)stmt,"values CURRENT DATE "); strcpy((char*)stmt1,"values CURRENT TIME "); rc = SQLExecDirect( hstmt3, stmt, SQL_NTS) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLBindCol( hstmt3, 1, SQL_C_CHAR, dateOut , 11, &indicator); if ( rc != SQL_SUCCESS ) return (0); rc = SQLFetch( hstmt3 ); rc1 = SQLGetSQLCA(henv, hdbc, hstmt3, &sqlca); *out_sqlcode = SQLCODE; strcpy(buffer, "VALUES CURRENT DATE"); if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecDirect( hstmt4, stmt1, SQL_NTS) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLBindCol( hstmt4, 1, SQL_C_CHAR, timeOut , 9, &indicator); if ( rc != SQL_SUCCESS ) return (0); rc = SQLFetch( hstmt4 ); rc1 = SQLGetSQLCA(henv, hdbc, hstmt4, &sqlca); *out_sqlcode = SQLCODE; strcpy(buffer, "VALUES CURRENT TIME"); if ( rc != SQL_SUCCESS ) return (0); rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt1 ) ; rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt2 ) ; rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt3 ) ; rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt4 ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; 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 ) ; rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; return (0); } /* end all_data_types procedure */ SQL_API_RC SQL_API_FN dbinfo_example ( char injob[9], /* Input - CHAR(8) */ double *salary, /* Output - DOUBLE */ char dbname[129], /* Output - database name from DBINFO */ char dbversion[9], /* Output - database version from DBINFO */ sqlint32 *out_sqlcode, struct sqludf_dbinfo *dbinfo /* Pointer to DBINFO structure */ ) { int counter = 0; SQLHANDLE henv, hdbc, hstmt ; SQLRETURN rc,rc1 ; SQLCHAR stmt[100]; sqlint32 indicator; struct sqlca sqlca; /*-----------------------------------------------------------------*/ /* Setup CLI required environment */ /*-----------------------------------------------------------------*/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); /*-----------------------------------------------------------------*/ /* Issue NULL Connect, since in CLI we need a statement handle */ /* and thus a connection handle and environment handle. */ /* A connection is not established, rather the current */ /* connection from the calling application is used */ /*-----------------------------------------------------------------*/ SQLCODE = 0; SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ; rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; if ( rc != SQL_SUCCESS ) return (0); strcpy((char*)stmt,"SELECT AVG(salary) FROM employee WHERE job = ?"); rc = SQLPrepare(hstmt, stmt, SQL_NTS); if ( rc != SQL_SUCCESS ) return (0); /* Bind the parameter to application variables () */ rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,0, 0, injob, 9, NULL); if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecute(hstmt); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; if ( rc != SQL_SUCCESS ) return (0); /* bind columns to variables */ rc = SQLBindCol( hstmt, 1, SQL_C_DOUBLE, salary , 0, &indicator); if ( rc != SQL_SUCCESS ) return (0); rc = SQLFetch( hstmt ); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; strcpy (dbname, (char *)(dbinfo->dbname)); strcpy (dbversion, (char *)(dbinfo->ver_rel)); if ( rc != SQL_SUCCESS ) return (0); rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; 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 ) ; rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; return (0); } /* end dbinfo_example function */ SQL_API_RC SQL_API_FN main_example ( int argc, char **argv) { char injob[9]; double *salary=NULL; int counter = 0; SQLHANDLE henv, hdbc, hstmt ; SQLRETURN rc,rc1 ; SQLCHAR stmt[100]; sqlint32 indicator; struct sqlca sqlca; /*-----------------------------------------------------------------*/ /* Setup CLI required environment */ /*-----------------------------------------------------------------*/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); /*-----------------------------------------------------------------*/ /* Issue NULL Connect, since in CLI we need a statement handle */ /* and thus a connection handle and environment handle. */ /* A connection is not established, rather the current */ /* connection from the calling application is used */ /*-----------------------------------------------------------------*/ SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ; strcpy (injob, (char *)argv[1]); SQLCODE = 0; salary = (double * ) malloc ( sizeof (double)); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; if ( rc != SQL_SUCCESS ) return (0); strcpy((char*)stmt,"SELECT AVG(salary) FROM employee WHERE job = ?"); rc = SQLPrepare(hstmt, stmt, SQL_NTS); if ( rc != SQL_SUCCESS ) return (0); /* Bind the parameter to application variables () */ rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,0, 0, injob, 9, NULL); if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecute(hstmt); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); memcpy ((sqlint32 *)argv[3], (sqlint32 *)&SQLCODE, sizeof(sqlint32)); if ( rc != SQL_SUCCESS ) return (0); /* bind columns to variables */ rc = SQLBindCol( hstmt, 1, SQL_C_DOUBLE, salary , 0, &indicator); if ( rc != SQL_SUCCESS ) return (0); rc = SQLFetch( hstmt ); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); memcpy ((sqlint32 *)argv[3], (sqlint32 *)&SQLCODE, sizeof(sqlint32)); if ( rc != SQL_SUCCESS ) return (0); memcpy ((double *)argv[2], (double *)salary, sizeof(double)); memcpy ((sqlint32 *)argv[3], (sqlint32 *)&SQLCODE, sizeof(sqlint32)); rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; 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 ) ; rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; return (0); } /* end main_example function */ SQL_API_RC SQL_API_FN db2sql_example ( char injob[9], /* Input - CHAR(8) */ double *salary, /* Output - DOUBLE */ sqlint16 nullinds[2], /* Inout - Array[n] of null indicators where */ /* n = number of parameters declared by user */ char sqlst[6], /* Output - SQLSTATE as CHAR(5) */ char qualname[28], /* Input - qualified name as CHAR(27) */ char specname[19], /* Input - specific name as CHAR(18) */ char diagmsg[71] /* Output - diagnostic message as CHAR(70) */ ) { int counter = 0; SQLHANDLE henv, hdbc, hstmt ; SQLRETURN rc,rc1 ; SQLCHAR stmt[100]; sqlint32 indicator; struct sqlca sqlca; sqlint32 *out_sqlcode=NULL; out_sqlcode = (sqlint32 *) malloc ( sizeof (sqlint32)); *salary = 0; if (nullinds[0] < 0) { /* NULL value was received as input, so return NULL output */ /* Using the RETURNS NULL ON NULL CALL clause in your CREATE PROCEDURE statement is more efficient */ nullinds[1] = -1; /* Set custom SQLSTATE to return to client. */ strcpy(sqlst, "38100"); /* Set custom message to return to client. Note that although the OUT parameter is declared as CHAR(70), DB2 prepends the procedure name and shared library entry point to the message. Keep the custom message short to avoid truncation. */ strcpy(diagmsg, "Received null input."); return (0); } /*-----------------------------------------------------------------*/ /* Setup CLI required environment */ /*-----------------------------------------------------------------*/ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); /*-----------------------------------------------------------------*/ /* Issue NULL Connect, since in CLI we need a statement handle */ /* and thus a connection handle and environment handle. */ /* A connection is not established, rather the current */ /* connection from the calling application is used */ /*-----------------------------------------------------------------*/ SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ; rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; if ( rc != SQL_SUCCESS ) return (0); strcpy((char*)stmt,"SELECT (CAST(AVG(salary) AS DOUBLE)) FROM employee "); strcat((char*)stmt,"where job = ?"); rc = SQLPrepare(hstmt, stmt, SQL_NTS); if ( rc != SQL_SUCCESS ) return (0); /* Bind the parameter to application variables () */ rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,0, 0, injob, 9, NULL); if ( rc != SQL_SUCCESS ) return (0); rc = SQLExecute(hstmt); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; /* bind columns to variables */ rc = SQLBindCol( hstmt, 1, SQL_C_DOUBLE, salary , 0, &indicator); HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return (0); rc = SQLFetch( hstmt ); rc1 = SQLGetSQLCA(henv, hdbc, hstmt, &sqlca); *out_sqlcode = SQLCODE; if ( rc != SQL_SUCCESS ) return (0); rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; 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 ) ; rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; HANDLE_CHECK( SQL_HANDLE_DBC, hdbc, rc, &henv, &hdbc ) ; return (0); } /* end db2sql_example function */