#ifdef _WIN32 #include #endif #include #include #include #include SQLHENV henv; SQLHDBC hdbc; SQLHSTMT hstmt; #define ok_something(A, B, C) rc= B; if (rc != SQL_SUCCESS){ \ error_num= PrintError(C, A, rc); \ goto PROGRAM_END; \ } #define ok_something2(A, B, C) rc= B; if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO){ \ error_num= PrintError(C, A, rc); \ goto PROGRAM_END; \ } #define FAIL -1 #define ok_env(A, B) ok_something(A,B, SQL_HANDLE_ENV) #define ok_dbc(A, B) ok_something(A,B, SQL_HANDLE_DBC) #define ok_stmt(A, B) ok_something(A,B, SQL_HANDLE_STMT) #define ok_env2(A, B) ok_something2(A,B, SQL_HANDLE_ENV) #define ok_dbc2(A, B) ok_something2(A,B, SQL_HANDLE_DBC) #define ok_stmt2(A, B) ok_something2(A,B, SQL_HANDLE_STMT) #define ok_sql(A, B) ok_stmt(A, SQLExecDirect(A, B, SQL_NTS)) #define is_str(a, b, c) \ do { \ char *val_a= (char *)(a), *val_b= (char *)(b); \ int val_len= (int)(c); \ if (strncmp(val_a, val_b, val_len) != 0) { \ printf("# %s ('%*s') != '%*s' in %s on line %d\n", \ #a, val_len, val_a, val_len, val_b, __FILE__, __LINE__); \ return FAIL; \ } \ } while (0); #define expect_odbc(hnd, type, call, expect) \ do { \ SQLRETURN rc= (call); \ if (rc != (expect)) \ { \ PrintError((type), (hnd), rc); \ printf("# Expected %d, but got %d in %s on line %d\n", (expect), rc, \ __FILE__, __LINE__); \ goto PROGRAM_END; \ } \ } while (0) #define expect_env(env, call, expect) \ expect_odbc((env), SQL_HANDLE_STMT, (call), (expect)) #define expect_dbc(dbc, call, expect) \ expect_odbc((dbc), SQL_HANDLE_STMT, (call), (expect)) #define expect_stmt(statement, call, expect) \ expect_odbc((statement), SQL_HANDLE_STMT, (call), (expect)) #define expect_desc(desc, call, expect) \ expect_odbc((desc), SQL_HANDLE_DESC, (call), (expect)) /** Verify that a number (long integer) matches an expected value. @param a The number to compare @param b The number to compare against */ #define is_num(a, b) \ do { \ long long a1= (a), a2= (b); \ if (a1 != a2) { \ printf("# %s (%lld) != %lld in %s on line %d\n", \ #a, a1, a2, __FILE__, __LINE__); \ goto PROGRAM_END; \ } \ } while (0); SQLINTEGER PrintError(SQLSMALLINT handleType, SQLHANDLE handle, SQLRETURN rcode) { SQLRETURN rc = SQL_ERROR; SQLCHAR sqlState[6]; SQLCHAR eMsg[SQL_MAX_MESSAGE_LENGTH]; SQLINTEGER nError; SQLSMALLINT msgLen; if (rcode == SQL_NO_DATA) { printf( "NO DATA .. .. .."); return(SQL_NO_DATA); } else { rc = SQLGetDiagRec(handleType, handle, 1, sqlState, &nError, eMsg, sizeof(eMsg), &msgLen); if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { printf( " Error: %s\n", eMsg); } return (SQL_ERROR); } } int main() { SQLRETURN rc= 0; int error_num= 0; SQLLEN cbresult= 0; #define BUF_LEN 128 SQLSMALLINT col_count= 0, name_len=0 , data_type= 0; SQLSMALLINT dec_digits=0, nullable= 0; SQLUINTEGER col_size= 0; SQLINTEGER strlen_or_ind= 0; SQLULEN pcrow= 0; SQLUSMALLINT rgfRowStatus= 0; const SQLCHAR key_column_name[][128]= {"User_ID", "Max_Update_Time"}; SQLCHAR catalog[BUF_LEN], schema[BUF_LEN], table[BUF_LEN], column[BUF_LEN]; SQLLEN catalog_len, schema_len, table_len, column_len; SQLCHAR keyname[BUF_LEN]; SQLSMALLINT key_seq, i; SQLLEN keyname_len, key_seq_len, rowCount; SQLAllocHandle(SQL_HANDLE_ENV,NULL,&henv); SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc); /* CHANGE THE CONNECTION STRING BELOW */ SQLDriverConnect(hdbc, 0, "DSN=test", SQL_NTS, 0, 0, 0, 0); printf("\nConnected!\n"); ok_dbc(hdbc, SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt)); ok_sql(hstmt, "drop table if exists `123sda`"); ok_sql(hstmt, "CREATE TABLE `123sda` ( " \ "`User_ID` VARCHAR(50) NOT NULL, " \ "`Max_Update_Time` DATETIME NOT NULL," \ "`Sum_Sec` INT NULL," \ "`Update_Type` VARCHAR(254) NULL," \ "PRIMARY KEY (`User_ID`, `Max_Update_Time`))"); printf("\nCreating table..."); ok_stmt(hstmt, SQLPrimaryKeys(hstmt, NULL, SQL_NTS, NULL, SQL_NTS, "123sda", SQL_NTS)); printf("\nRequesting Keys..."); /* Test of SQLRowCount with SQLPrimaryKeys */ ok_stmt(hstmt, SQLRowCount(hstmt, &rowCount)); is_num(rowCount, 2); ok_stmt(hstmt, SQLBindCol(hstmt, 1, SQL_C_CHAR , catalog, sizeof(catalog), &catalog_len)); ok_stmt(hstmt, SQLBindCol(hstmt, 2, SQL_C_CHAR , schema , sizeof(schema) , &schema_len)); ok_stmt(hstmt, SQLBindCol(hstmt, 3, SQL_C_CHAR , table , sizeof(table) , &table_len)); ok_stmt(hstmt, SQLBindCol(hstmt, 4, SQL_C_CHAR , column , sizeof(column) , &column_len)); ok_stmt(hstmt, SQLBindCol(hstmt, 5, SQL_C_SHORT,&key_seq, sizeof(key_seq), &key_seq_len)); ok_stmt(hstmt, SQLBindCol(hstmt, 6, SQL_C_CHAR , keyname, sizeof(keyname), &keyname_len)); for(i= 0; i < 2; ++i) { ok_stmt(hstmt, SQLFetch(hstmt)); printf("\nROW # %d", i + 1); is_num(catalog_len, SQL_NULL_DATA); is_num(schema_len, SQL_NULL_DATA); is_str(table, "123sda", 3); is_str(column, key_column_name[i], 4); is_num(key_seq, i+1); is_str(keyname, "PRIMARY", 6); printf("\nTable: %s, Column: %s, Key Seq: %d, Key Name: %s", table, column, key_seq, keyname); } printf("\nDONE!"); expect_stmt(hstmt, SQLFetch(hstmt), SQL_NO_DATA); ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE)); ok_sql(hstmt, "drop table if exists `123sda`"); return 0; PROGRAM_END: printf("\nExited with error"); return -1; }