#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 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 MAX_MEM_BLOCK_ELEMENTS 100 typedef struct { void *blk[MAX_MEM_BLOCK_ELEMENTS]; int counter; } GCOLL; GCOLL gc_blk; /* Allocate size bytes and return a pointer to allocated memory with storing in garbage collector */ void *gc_alloc(size_t len) { if (gc_blk.counter >= MAX_MEM_BLOCK_ELEMENTS || len <= 0) { printf("# GC Memory reached maximum limit counter: %d " \ "or length:%d less then equal to 0 in %s on line %d\n", gc_blk.counter, len, __FILE__, __LINE__); \ return NULL; } gc_blk.blk[gc_blk.counter]= malloc(len); return gc_blk.blk[gc_blk.counter++]; } /** Helper for converting a (char *) to a (SQLWCHAR *) */ #define WC(string) dup_char_as_sqlwchar((string)) /** Convert a char * to a SQLWCHAR *. New space is allocated and never freed. Because this is used in short-lived test programs, this is okay, if not ideal. */ SQLWCHAR *dup_char_as_sqlwchar(SQLCHAR *from) { SQLWCHAR *to= gc_alloc((strlen((char *)from) + 1) * sizeof(SQLWCHAR)); SQLWCHAR *out= to; while (from && *from) *(to++)= (SQLWCHAR)*(from++); *to= 0; return out; } 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; SQLCHAR result[255]; SQLLEN cbresult= 0; SQLAllocHandle(SQL_HANDLE_ENV,NULL,&henv); SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc); SQLDriverConnect(hdbc, 0, "DSN=test52a", SQL_NTS, 0, 0, 0, 0); printf("Connected!\n"); ok_dbc(hdbc, SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt)); ok_stmt(hstmt, SQLExecDirect(hstmt, "SELECT 'Петя'", SQL_NTS)); ok_stmt(hstmt, SQLFetch(hstmt)); ok_stmt(hstmt, SQLGetData(hstmt, 1, SQL_C_CHAR, result, sizeof(result), &cbresult)); printf("Result: [%s]\n", (char*)result); printf("Done!\n"); PROGRAM_END: SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 0; }