/******************************************************************************* ** ** Source File Name = browser.c 1.4 ** ** 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 : ** Prompts for a Schema and table search pattern string. ** Display a list of tables that macth the search pattern. ** Allows the user to select a varitey of catalog information, ** for each of the tables. ** ** 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 <string.h> #include <stdlib.h> #include <sqlcli1.h> #include "samputil.h" /* Header file for CLI sample code */ /* For the Macintosh environment when generating 68K applications */ #ifdef DB268K /* Need to include ASLM for 68K applications */ #include <LibraryManager.h> #endif #define MAX_STMT_LEN 255 #ifdef DB2WIN #define MAX_TABLES 50 #else #define MAX_TABLES 255 #endif SQLRETURN init_tables( SQLHANDLE ) ; SQLRETURN print_tables(void) ; SQLRETURN list_table_privileges( SQLHANDLE, SQLCHAR *, SQLCHAR * ) ; SQLRETURN list_columns( SQLHANDLE, SQLCHAR *, SQLCHAR * ) ; SQLRETURN list_primary_keys( SQLHANDLE, SQLCHAR *, SQLCHAR * ) ; SQLRETURN list_index_columns( SQLHANDLE, SQLCHAR *, SQLCHAR * ) ; SQLRETURN list_column_privileges( SQLHANDLE, SQLCHAR *, SQLCHAR * ) ; SQLRETURN list_foreign_keys( SQLHANDLE, SQLCHAR *, SQLCHAR * ) ; SQLRETURN list_stats( SQLHANDLE, SQLCHAR *, SQLCHAR * ) ; /* 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] ; /* Global Table structure */ typedef struct { SQLINTEGER schem_l ; SQLCHAR schem[129] ; SQLINTEGER name_l ; SQLCHAR name[129] ; SQLINTEGER type_l ; SQLCHAR type[129] ; SQLINTEGER remarks_l ; SQLCHAR remarks[255] ; } table_info ; table_info table[MAX_TABLES] ; SQLSMALLINT num_tables ; /******************************************************************* ** main ** - initialize ** - terminate *******************************************************************/ int main( int argc, char * argv[] ) { SQLHANDLE henv, hdbc, hstmt ; SQLRETURN rc ; SQLINTEGER tnum; int state ; char line[256]; char action; /* For the Macintosh environment when generating 68K applications */ #ifdef DB268K /* Before making any API calls for 68K environment, need to initialize the Library Manager */ InitLibraryManager(0,kCurrentZone,kNormalMemory); atexit(CleanupLibraryManager); #endif /* macro to initalize server, uid and pwd */ INIT_UID_PWD ; /* allocate an environment handle */ rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; if ( rc != SQL_SUCCESS ) return( terminate( henv, rc ) ) ; /* allocate a connect handle, and connect */ rc = DBconnect( henv, &hdbc ) ; if ( rc != SQL_SUCCESS ) return( terminate( henv, rc ) ) ; rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; CHECK_HANDLE( SQL_HANDLE_DBC, hdbc, rc ) ; if ( init_tables( hstmt ) != SQL_SUCCESS) exit( -1 ) ; rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; CHECK_HANDLE( SQL_HANDLE_DBC, hdbc, rc ) ; state = 0 ; while ( state == 0 ) { rc = print_tables(); printf("Enter a table Number and an action:" "(n [Q | C | P | I | F | T |O | L]) \n"); printf( "|Q=Quit C=cols P=Primary Key I=Index F=Foreign Key |\n" "|T=Tab Priv O=Col Priv S=Stats L=List Tables |\n"); fgets(line, 255, stdin); if (sscanf(line, "%i %c", &tnum, &action) == 2) { switch ( action ) { case 'q' : case 'Q' : state = 1; break; case 'c' : case 'C' : { rc = list_columns( hstmt, table[tnum-1].schem, table[tnum-1].name); state = 0; break; } case 'p' : case 'P' : { rc = list_primary_keys( hstmt, table[tnum-1].schem, table[tnum-1].name); state = 0; break; } case 't' : case 'T' : { rc = list_table_privileges( hstmt, table[tnum-1].schem, table[tnum-1].name); state = 0; break; } case 'o' : case 'O' : { rc = list_column_privileges( hstmt, table[tnum-1].schem, table[tnum-1].name); state = 0; break; } case 'i' : case 'I' : { rc = list_index_columns( hstmt, table[tnum-1].schem, table[tnum-1].name); state = 0; break; } case 'f' : case 'F' : { rc = list_foreign_keys( hstmt, table[tnum-1].schem, table[tnum-1].name); state = 0; break; } case 's' : case 'S' : { rc = list_stats( hstmt, table[tnum-1].schem, table[tnum-1].name); state = 0; break; } case 'l' : case 'L' : { rc = init_tables( hstmt ); state = 0; break; } default : { printf(">> Hit Enter to Continue<<\n"); fgets(line, 255, stdin); break; } } /* switch statement */ } /* if statement */ if ((rc = sscanf(line, "%c", &action)) == 1) { switch ( action ) { case 'q' : case 'Q' : state = 1; break; case 'l' : case 'L' : { rc = init_tables( hstmt ); state = 0; break; } default : { printf(">> Hit Enter to Continue<<\n"); fgets(line, 255, stdin); break; } } } } rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; CHECK_HANDLE( SQL_HANDLE_DBC, hdbc, rc ) ; rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; printf( "\n>Disconnecting .....\n" ) ; rc = SQLDisconnect( hdbc ) ; CHECK_HANDLE( SQL_HANDLE_DBC, hdbc, rc ) ; rc = SQLFreeHandle( SQL_HANDLE_DBC, hdbc ) ; CHECK_HANDLE( SQL_HANDLE_DBC, hdbc, rc ) ; rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; if ( rc != SQL_SUCCESS ) return( terminate( henv, rc ) ) ; return( SQL_SUCCESS ) ; } /* end main */ /**************************************************************************/ /* init_tables */ /* - prompts for schema and table search patterns, initializes array */ /* */ /**************************************************************************/ /*--> SQLL1X50.SCRIPT */ SQLRETURN init_tables( SQLHANDLE hstmt ) { SQLRETURN rc ; SQLUSMALLINT rowstat[MAX_TABLES]; SQLUINTEGER pcrow; /* SQL_ROWSET_SIZE sets the max number of result rows to fetch each time */ rc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_ARRAY_SIZE, ( SQLPOINTER ) MAX_TABLES, 0 ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; /* Set Size of One row, Used for Row-Wise Binding Only */ rc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_BIND_TYPE, ( SQLPOINTER ) sizeof( table_info ), 0 ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_STATUS_PTR, ( SQLPOINTER ) rowstat, 0 ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROWS_FETCHED_PTR, ( SQLPOINTER ) &pcrow, 0 ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; printf("Enter Search Pattern for Table Schema Name:\n"); gets((char *)table->schem); printf("Enter Search Pattern for Table Name:\n"); gets((char *)table->name); rc = SQLTables(hstmt, NULL, 0, table->schem, SQL_NTS, table->name, SQL_NTS, NULL, 0); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 2, SQL_C_CHAR, (SQLPOINTER) table[0].schem, 129, &table[0].schem_l); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 3, SQL_C_CHAR, (SQLPOINTER) table[0].name, 129, &table[0].name_l); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 4, SQL_C_CHAR, (SQLPOINTER) table[0].type, 129, &table[0].type_l); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 5, SQL_C_CHAR, (SQLPOINTER) table[0].remarks, 255, &table[0].remarks_l); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; /* Now fetch the result set */ /*<-- */ /* Fetch up to MAX_TABLES into table array */ rc = SQLFetchScroll( hstmt, SQL_FETCH_NEXT, 0 ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; num_tables = pcrow; /* Keep track of the number of valid rows in table */ /* free statement resources */ rc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_ARRAY_SIZE, ( SQLPOINTER ) 1, 0 ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_BIND_TYPE, ( SQLPOINTER ) NULL, 0 ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_STATUS_PTR, ( SQLPOINTER ) NULL, 0 ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROWS_FETCHED_PTR, ( SQLPOINTER ) NULL, 0 ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_UNBIND ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_RESET_PARAMS ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_CLOSE ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; return( rc ) ; } /* end init_tables */ SQLRETURN print_tables() { SQLSMALLINT tnum ; printf("### TABLE SCHEMA TABLE_NAME TABLE_TYPE\n"); printf(" ------------------------- ------------------------- ----------\n"); /* Display each Row from table array */ for (tnum = 0; tnum < num_tables; tnum++) { printf("%-3d %-25s %-25s %-11s\n", tnum + 1, table[tnum].schem, table[tnum].name, table[tnum].type); if (table[tnum].remarks_l > 0 ) { printf(" (remarks) %s\n", table[tnum].remarks); } } return (SQL_SUCCESS); } /* end print tables */ /**************************************************************************/ /* list_table_privileges */ /* - This sample function assumes that schema and tablename are exact */ /* strings, NOT search patterns */ /* */ /**************************************************************************/ /*--> SQLL1X51.SCRIPT */ SQLRETURN list_table_privileges( SQLHANDLE hstmt, SQLCHAR * schema, SQLCHAR * tablename ) { SQLRETURN rc; struct { SQLINTEGER ind; /* Length & Indicator variable */ SQLCHAR s[129]; /* String variable */ } grantor, grantee, privilege; struct { SQLINTEGER ind; SQLCHAR s[4]; }is_grantable; SQLCHAR cur_name[512] = ""; /* Used when printing the */ SQLCHAR pre_name[512] = ""; /* Result set */ /* Create Table Privilges result set */ rc = SQLTablePrivileges(hstmt, NULL, 0, schema, SQL_NTS, tablename, SQL_NTS); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 4, SQL_C_CHAR, (SQLPOINTER) grantor.s, 129, &grantor.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; /* Continue Binding, then fetch and display result set */ /*<-- */ rc = SQLBindCol(hstmt, 5, SQL_C_CHAR, (SQLPOINTER) grantee.s, 129, &grantee.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 6, SQL_C_CHAR, (SQLPOINTER) privilege.s, 129, &privilege.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 7, SQL_C_CHAR, (SQLPOINTER) is_grantable.s, 4, &is_grantable.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; printf("Current User's Privileges for: %s.%s\n", schema, tablename); printf(" Grantor Grantee Privilege Grantable\n"); printf(" --------------- --------------- ---------- ---\n"); /* Fetch each row, and display */ while ((rc = SQLFetch(hstmt)) == SQL_SUCCESS) { printf(" %-15s", grantor.s); printf(" %-15s", grantee.s); printf(" %-10s", privilege.s); printf(" %-3s\n", is_grantable.s); } /* endwhile */ if (rc != SQL_NO_DATA_FOUND) CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; /* free statement resources */ rc = SQLFreeStmt( hstmt, SQL_UNBIND ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_RESET_PARAMS ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_CLOSE ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; return( SQL_SUCCESS ) ; } /**************************************************************************/ /* list_columns */ /* - schema and tablename should be exact strings, NOT search patterns */ /* */ /**************************************************************************/ /*--> SQLL1X52.SCRIPT */ SQLRETURN list_columns( SQLHANDLE hstmt, SQLCHAR * schema, SQLCHAR * tablename ) { /*<-- */ SQLRETURN rc; struct { SQLINTEGER ind; SQLCHAR s[129]; } column_name, type_name, remarks; SQLINTEGER length; SQLINTEGER length_ind; SQLSMALLINT scale; SQLINTEGER scale_ind; SQLSMALLINT nullable; SQLINTEGER nullable_ind; /*--> */ rc = SQLColumns(hstmt, NULL, 0, schema, SQL_NTS, tablename, SQL_NTS, (SQLCHAR *)"%", SQL_NTS); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 4, SQL_C_CHAR, (SQLPOINTER) column_name.s, 129, &column_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 6, SQL_C_CHAR, (SQLPOINTER) type_name.s, 129, &type_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 7, SQL_C_LONG, (SQLPOINTER) &length, sizeof(length), &length_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 9, SQL_C_SHORT, (SQLPOINTER) &scale, sizeof(scale), &scale_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 12, SQL_C_CHAR, (SQLPOINTER) remarks.s, 129, &remarks.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 11, SQL_C_SHORT, (SQLPOINTER) & nullable, sizeof(nullable), &nullable_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; printf("Schema: %s Table Name: %s\n", schema, tablename); /* Fetch each row, and display */ while ((rc = SQLFetch(hstmt)) == SQL_SUCCESS) { printf(" %s", column_name.s); if (nullable == SQL_NULLABLE) { printf(", NULLABLE"); } else { printf(", NOT NULLABLE"); } printf(", %s", type_name.s); if (length_ind != SQL_NULL_DATA) { printf(" (%ld", length); } else { printf("(\n"); } if (scale_ind != SQL_NULL_DATA) { printf(", %d)\n", scale); } else { printf(")\n"); } } /* endwhile */ /*<-- */ if ( rc != SQL_NO_DATA_FOUND ) CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; /* free statement resources */ rc = SQLFreeStmt( hstmt, SQL_UNBIND ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_RESET_PARAMS ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_CLOSE ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; return( SQL_SUCCESS ) ; } /* list_columns */ /**************************************************************************/ /* list_primary_keys */ /* - schema and tablename should be exact strings, NOT search patterns */ /* */ /**************************************************************************/ /*--> SQLL1X57.SCRIPT */ SQLRETURN list_primary_keys( SQLHANDLE hstmt, SQLCHAR * schema, SQLCHAR * tablename ) { /*<-- */ SQLRETURN rc; struct { SQLINTEGER ind; SQLCHAR s[129]; } column_name, pk_name; SQLSMALLINT ord_pos; /*--> */ rc = SQLPrimaryKeys(hstmt, NULL, 0, schema, SQL_NTS, tablename, SQL_NTS); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 4, SQL_C_CHAR, (SQLPOINTER) column_name.s, 129, &column_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 5, SQL_C_SHORT, (SQLPOINTER) &ord_pos, 0, NULL); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 6, SQL_C_CHAR, (SQLPOINTER) pk_name.s, 129, &pk_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; printf("Primary Keys for %s.%s\n", schema, tablename); /* Fetch each row, and display */ while ((rc = SQLFetch(hstmt)) == SQL_SUCCESS) { printf(" %ld Column: %-18s ", ord_pos, column_name.s); if (pk_name.ind == SQL_NULL_DATA) printf(" Primary Key Name: = NULL\n"); else printf(" Primary Key Name: = %ld\n", pk_name.s); } /* endwhile */ /*<-- */ if ( rc != SQL_NO_DATA_FOUND ) CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; /* free statement resources */ rc = SQLFreeStmt( hstmt, SQL_UNBIND ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_RESET_PARAMS ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_CLOSE ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; return( SQL_SUCCESS ) ; } /* list_primary_keys*/ /**************************************************************************/ /* list_column_privileges */ /* - schema and tablename must be exact strings, NOT search patterns */ /**************************************************************************/ /*--> SQLL1X53.SCRIPT */ SQLRETURN list_column_privileges( SQLHANDLE hstmt, SQLCHAR * schema, SQLCHAR * tablename ) { /*<--*/ SQLRETURN rc; struct { SQLINTEGER ind; SQLCHAR s[129]; } columnname, grantor, grantee, privilege; struct { SQLINTEGER ind; SQLCHAR s[4]; }is_grantable; SQLCHAR cur_name[512] = ""; SQLCHAR pre_name[512] = ""; printf("Enter Search Pattern for Column Name:\n"); gets((char *)columnname.s); /*--> */ rc = SQLColumnPrivileges(hstmt, NULL, 0, schema, SQL_NTS, tablename, SQL_NTS, columnname.s, SQL_NTS); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 4, SQL_C_CHAR, (SQLPOINTER) columnname.s, 129, &columnname.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 5, SQL_C_CHAR, (SQLPOINTER) grantor.s, 129, &grantor.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 6, SQL_C_CHAR, (SQLPOINTER) grantee.s, 129, &grantee.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 7, SQL_C_CHAR, (SQLPOINTER) privilege.s, 129, &privilege.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 8, SQL_C_CHAR, (SQLPOINTER) is_grantable.s, 4, &is_grantable.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; printf("Column Privileges for %s.%s\n", schema, tablename); /* Fetch each row, and display */ while ((rc = SQLFetch(hstmt)) == SQL_SUCCESS) { sprintf((char *)cur_name, " Column: %s\n", columnname.s); if (strcmp((char *)cur_name, (char *)pre_name) != 0) { printf("\n%s\n", cur_name); printf(" Grantor Grantee Privilege Grantable\n"); printf(" --------------- --------------- ---------- ---\n"); } strcpy((char *)pre_name, (char *)cur_name); printf(" %-15s", grantor.s); printf(" %-15s", grantee.s); printf(" %-10s", privilege.s); printf(" %-3s\n", is_grantable.s); } /* endwhile */ /*<-- */ if ( rc != SQL_NO_DATA_FOUND ) CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; /* free statement resources */ rc = SQLFreeStmt( hstmt, SQL_UNBIND ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_RESET_PARAMS ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_CLOSE ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; return( SQL_SUCCESS ) ; } /* list_column_privileges */ /**************************************************************************/ /* list_Foreign_Keys */ /* - schema and tablename must be exact strings, NOT search patterns */ /**************************************************************************/ /*--> SQLL1X54.SCRIPT */ SQLRETURN list_foreign_keys( SQLHANDLE hstmt, SQLCHAR * schema, SQLCHAR * tablename ) { /*<-- */ SQLRETURN rc; struct { SQLINTEGER ind; SQLCHAR s[129]; } pktable_schem, pktable_name, pkcolumn_name, pkey_name; struct { SQLINTEGER ind; SQLCHAR s[129]; } fktable_schem, fktable_name, fkcolumn_name, fkey_name; SQLSMALLINT delete_rule; SQLINTEGER update_ind; SQLSMALLINT update_rule; SQLINTEGER delete_ind; /*--> */ rc = SQLForeignKeys(hstmt, NULL, 0, schema, SQL_NTS, tablename, SQL_NTS, NULL, 0, NULL, SQL_NTS, NULL, SQL_NTS); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 2, SQL_C_CHAR, (SQLPOINTER) pktable_schem.s, 129, &pktable_schem.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 3, SQL_C_CHAR, (SQLPOINTER) pktable_name.s, 129, &pktable_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 4, SQL_C_CHAR, (SQLPOINTER) pkcolumn_name.s, 129, &pkcolumn_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 6, SQL_C_CHAR, (SQLPOINTER) fktable_schem.s, 129, &fktable_schem.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 7, SQL_C_CHAR, (SQLPOINTER) fktable_name.s, 129, &fktable_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 8, SQL_C_CHAR, (SQLPOINTER) fkcolumn_name.s, 129, &fkcolumn_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 10, SQL_C_SHORT, (SQLPOINTER) &update_rule, 0, &update_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 11, SQL_C_SHORT, (SQLPOINTER) &delete_rule, 0, &delete_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 12, SQL_C_CHAR, (SQLPOINTER) fkey_name.s, 129, &fkey_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 13, SQL_C_CHAR, (SQLPOINTER) pkey_name.s, 129, &pkey_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; printf("Primary Key and Foreign Keys for %s.%s\n", schema, tablename); /* Fetch each row, and display */ while ((rc = SQLFetch(hstmt)) == SQL_SUCCESS) { printf(" %s %s.%s.%s\n Update Rule ", pkcolumn_name.s, fktable_schem.s, fktable_name.s, fkcolumn_name.s); if (update_rule == SQL_RESTRICT) { printf("RESTRICT "); /* always for IBM DBMSs */ } else { if (update_rule == SQL_CASCADE) { printf("CASCADE "); /* non-IBM only */ } else { printf("SET NULL "); } } printf(", Delete Rule: "); if (delete_rule== SQL_RESTRICT) { printf("RESTRICT "); /* always for IBM DBMSs */ } else { if (delete_rule == SQL_CASCADE) { printf("CASCADE "); /* non-IBM only */ } else { if (delete_rule == SQL_NO_ACTION) { printf("NO ACTION "); /* non-IBM only */ } else { printf("SET NULL "); } } } printf("\n"); if (pkey_name.ind > 0 ) { printf(" Primary Key Name: %s\n", pkey_name.s); } if (fkey_name.ind > 0 ) { printf(" Foreign Key Name: %s\n", fkey_name.s); } } /*<-- */ if ( rc != SQL_NO_DATA_FOUND ) CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; /* free statement resources */ rc = SQLFreeStmt( hstmt, SQL_UNBIND ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_RESET_PARAMS ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_CLOSE ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; return( SQL_SUCCESS ) ; } /* End List Foreign Keys */ /**************************************************************************/ /* list_index_columns */ /* - schema and tablename must be exact strings, NOT search patterns */ /**************************************************************************/ /*--> SQLL1X55.SCRIPT */ SQLRETURN list_index_columns( SQLHANDLE hstmt, SQLCHAR * schema, SQLCHAR * tablename ) { /*<-- */ SQLRETURN rc; struct { SQLINTEGER ind; SQLCHAR s[129]; } column_name, type_name; struct { SQLINTEGER ind; SQLCHAR s[255]; } remarks; SQLINTEGER precision; SQLINTEGER precision_ind; SQLSMALLINT scale; SQLINTEGER scale_ind; SQLSMALLINT nullable; /*--> */ rc = SQLSpecialColumns(hstmt, SQL_BEST_ROWID, NULL, 0, schema, SQL_NTS, tablename, SQL_NTS, SQL_SCOPE_CURROW, SQL_NULLABLE); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 2, SQL_C_CHAR, (SQLPOINTER) column_name.s, 129, &column_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 4, SQL_C_CHAR, (SQLPOINTER) type_name.s, 129, &type_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 5, SQL_C_LONG, (SQLPOINTER) & precision, sizeof(precision), &precision_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 7, SQL_C_SHORT, (SQLPOINTER) & scale, sizeof(scale), &scale_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; printf("Primary Key or Unique Index for %s.%s\n", schema, tablename); /* Fetch each row, and display */ while ((rc = SQLFetch(hstmt)) == SQL_SUCCESS) { printf(" %s, %s ", column_name.s, type_name.s); if (precision_ind != SQL_NULL_DATA) { printf(" (%ld", precision); } else { printf("(\n"); } if (scale_ind != SQL_NULL_DATA) { printf(", %d)\n", scale); } else { printf(")\n"); } } /*<-- */ if ( rc != SQL_NO_DATA_FOUND ) CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; /* free statement resources */ rc = SQLFreeStmt( hstmt, SQL_UNBIND ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_RESET_PARAMS ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_CLOSE ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; return( SQL_SUCCESS ) ; } /* end list_index_columns */ /**************************************************************************/ /* list_stats */ /* - schema and tablename should be exact strings, NOT search patterns */ /**************************************************************************/ /*--> SQLL1X56.SCRIPT */ SQLRETURN list_stats( SQLHANDLE hstmt, SQLCHAR * schema, SQLCHAR * tablename ) { /*<-- */ SQLRETURN rc; struct { SQLINTEGER ind; SQLCHAR s[129]; } index_name, column_name; SQLSMALLINT non_unique; SQLINTEGER non_unique_ind; SQLSMALLINT type; SQLINTEGER type_ind; SQLINTEGER cardinality; SQLINTEGER card_ind; SQLINTEGER pages; SQLINTEGER pages_ind; /*--> */ rc = SQLStatistics(hstmt, NULL, 0, schema, SQL_NTS, tablename, SQL_NTS, SQL_INDEX_UNIQUE, SQL_QUICK); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 4, SQL_C_SHORT, &non_unique, 2, &non_unique_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 6, SQL_C_CHAR, index_name.s, 129, &index_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 7, SQL_C_SHORT, &type, 2, &type_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 9, SQL_C_CHAR, column_name.s, 129, &column_name.ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 11, SQL_C_LONG, &cardinality, 4, &card_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLBindCol(hstmt, 12, SQL_C_LONG, &pages, 4, &pages_ind); CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; printf("Statistics for %s.%s\n", schema, tablename); while ((rc = SQLFetch(hstmt)) == SQL_SUCCESS) { if (type != SQL_TABLE_STAT) { printf(" Column: %-18s Index Name: %-18s\n", column_name.s, index_name.s); } else { printf(" Table Statistics:\n"); } if (card_ind != SQL_NULL_DATA) printf(" Cardinality = %13ld", cardinality); else printf(" Cardinality = (Unavailable)"); if (pages_ind != SQL_NULL_DATA) printf(" Pages = %13ld\n", pages); else printf(" Pages = (Unavailable)\n"); } /*<-- */ if ( rc != SQL_NO_DATA_FOUND ) CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; /* free statement resources */ rc = SQLFreeStmt( hstmt, SQL_UNBIND ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_RESET_PARAMS ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; rc = SQLFreeStmt( hstmt, SQL_CLOSE ) ; CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ; return( SQL_SUCCESS ) ; }