int main(int argc, char **argv) { SQLRETURN rc; HSTMT hstmt = SQL_NULL_HSTMT; char *param1, *param2; SQLLEN cbParam1, cbParam2; SQLLEN param1bytes, param2bytes; PTR paramid; SQLLEN str_ind_array[2]; SQLUSMALLINT status_array[2]; SQLULEN nprocessed = 0; int i; test_connect(); rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt); if (!SQL_SUCCEEDED(rc)) { print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn); exit(1); } /**** * Bind with data-at-execution params. (VARBINARY) */ /* Prepare a statement */ rc = SQLPrepare(hstmt, (SQLCHAR *) "SELECT id FROM byteatab WHERE t = ? OR t = ?", SQL_NTS); CHECK_STMT_RESULT(rc, "SQLPrepare failed", hstmt); /* prepare the parameter values */ param1 = "bar"; param1bytes = strlen(param1); cbParam1 = SQL_DATA_AT_EXEC; param2 = "foobar"; param2bytes = strlen(param2); cbParam2 = SQL_DATA_AT_EXEC; /* bind them. */ rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, /* value type */ SQL_VARBINARY, /* param type */ param1bytes, /* column size */ 0, /* dec digits */ (void *) 1, /* param value ptr. For a data-at-exec * param, this is a "parameter id" */ 0, /* buffer len */ &cbParam1 /* StrLen_or_IndPtr */); CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt); rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, /* value type */ SQL_VARBINARY, /* param type */ param2bytes, /* column size */ 0, /* dec digits */ (void *) 2, /* param value ptr. For a data-at-exec * param, this is a "parameter id" */ 0, /* buffer len */ &cbParam2 /* StrLen_or_IndPtr */); CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt); /* Execute */ rc = SQLExecute(hstmt); if (rc != SQL_NEED_DATA) CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt); /* set parameters */ paramid = 0; while ((rc = SQLParamData(hstmt, ¶mid)) == SQL_NEED_DATA) { if (paramid == (void *) 1) { rc = SQLPutData(hstmt, param1, param1bytes); CHECK_STMT_RESULT(rc, "SQLPutData failed", hstmt); } else if (paramid == (void *) 2) { rc = SQLPutData(hstmt, param2, param2bytes); CHECK_STMT_RESULT(rc, "SQLPutData failed", hstmt); } else { printf("unexpected parameter id returned by SQLParamData: %p\n", paramid); exit(1); } } CHECK_STMT_RESULT(rc, "SQLParamData failed", hstmt); /* Fetch result */ print_result(hstmt); rc = SQLFreeStmt(hstmt, SQL_CLOSE); CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); /**** * Array binding with data-at-execution params. */ /* prepare the parameter values */ str_ind_array[0] = SQL_DATA_AT_EXEC; str_ind_array[1] = SQL_DATA_AT_EXEC; /* Prepare a statement */ rc = SQLPrepare(hstmt, (SQLCHAR *) "SELECT id FROM byteatab WHERE t = ?", SQL_NTS); CHECK_STMT_RESULT(rc, "SQLPrepare failed", hstmt); SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0); SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, status_array, 0); SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &nprocessed, 0); SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) 2, 0); /* bind the array. */ rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, /* value type */ SQL_VARBINARY, /* param type */ 5, /* column size */ 0, /* dec digits */ (void *) 1, /* param value ptr. For a data-at-exec * param, this is "parameter id" */ 0, /* buffer len */ str_ind_array /* StrLen_or_IndPtr */); CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt); /* Execute */ rc = SQLExecute(hstmt); if (rc != SQL_NEED_DATA) CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt); /* set parameters */ paramid = 0; while ((rc = SQLParamData(hstmt, ¶mid)) == SQL_NEED_DATA) { if (nprocessed == 1) rc = SQLPutData(hstmt, "foo", strlen("foo")); else if (nprocessed == 2) rc = SQLPutData(hstmt, "barf", strlen("barf")); else { printf("unexpected # of rows processed after SQL_NEED_DATA: %u\n", (unsigned int) nprocessed); exit(1); } CHECK_STMT_RESULT(rc, "SQLPutData failed", hstmt); } CHECK_STMT_RESULT(rc, "SQLParamData failed", hstmt); /* Fetch results */ printf("Parameter Status\n"); for (i = 0; i < nprocessed; i++) { switch (status_array[i]) { case SQL_PARAM_SUCCESS: case SQL_PARAM_SUCCESS_WITH_INFO: break; case SQL_PARAM_ERROR: printf("%d\tError\n", i); break; case SQL_PARAM_UNUSED: printf("%d\tUnused\n", i); break; case SQL_PARAM_DIAG_UNAVAILABLE: printf("%d\tDiag unavailable\n", i); break; } } printf ("Fetching result sets for array bound (%u results expected)\n", (unsigned int) nprocessed); for (i = 1; rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO; i++) { printf("%d: ", i); print_result(hstmt); rc = SQLMoreResults(hstmt); } if (rc != SQL_NO_DATA) CHECK_STMT_RESULT(rc, "SQLMoreResults failed", hstmt); rc = SQLFreeStmt(hstmt, SQL_CLOSE); CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); /* Clean up */ test_disconnect(); return 0; }
int main() { SQLHENV env; SQLHDBC dbc; SQLHSTMT stmt; SQLRETURN ret; SQLCHAR outstr[1024]; SQLSMALLINT outstrlen; // Aloocate an environment handle ret=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&env); checkrc(ret,__LINE__); //we need odbc3 support SQLSetEnvAttr(env,SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3,0); //ALLOCATE A Connection handle ret = SQLAllocHandle(SQL_HANDLE_DBC,env,&dbc); checkrc(ret,__LINE__); // connect to the DSN mydsn ret = SQLConnect (dbc, (SQLCHAR *) "test", (SQLSMALLINT) strlen ("test"), (SQLCHAR *) "root", (SQLSMALLINT) strlen ("root"), (SQLCHAR *) "manager", (SQLSMALLINT) strlen ("")); if(SQL_SUCCEEDED(ret)) { printf("\nConnected to the Data Source..\n"); } else { printf("error in connection\n"); ret = SQLFreeHandle(SQL_HANDLE_DBC,dbc); checkrc(ret,__LINE__); ret = SQLFreeHandle(SQL_HANDLE_ENV,env); checkrc(ret,__LINE__); return 1; } //****************************************************************** // TABLE CREATED ret = SQLAllocHandle(SQL_HANDLE_STMT,dbc,&stmt); checkrc(ret,__LINE__); SQLCHAR table[200]= "CREATE TABLE T1(F1 INT,F2 SMALLINT,F3 CHAR(30),F4 FLOAT,F5 FLOAT,F6 DATE,F7 TIME,F8 TIMESTAMP,F9 TINYINT,F10 BIGINT)"; ret = SQLPrepare(stmt,table,SQL_NTS); checkrc(ret,__LINE__); ret = SQLExecute(stmt); checkrc(ret,__LINE__); printf("\nTABLE CREATED\n"); //***************************** InsertTest(env,dbc,stmt); DeleteTest(env,dbc,stmt); //**************************************************************** SQLCHAR drop[100]="DROP TABLE T1"; ret = SQLPrepare(stmt,drop,SQL_NTS); checkrc(ret,__LINE__); ret = SQLExecute(stmt); if(ret!=SQL_SUCCESS && ret !=SQL_SUCCESS_WITH_INFO) printf("Statement failed\n"); else printf("Table 'T1' dropped successfully\n"); ret = SQLFreeHandle(SQL_HANDLE_STMT,stmt); checkrc(ret,__LINE__); ret = SQLDisconnect(dbc); checkrc(ret,__LINE__); ret = SQLFreeHandle(SQL_HANDLE_DBC,dbc); checkrc(ret,__LINE__); ret = SQLFreeHandle(SQL_HANDLE_ENV,env); checkrc(ret,__LINE__); return 0; }
void TypeInfo::fillTypeInfo(SQLHDBC pHDBC) { _pHDBC = &pHDBC; if (_typeInfo.empty() && _pHDBC) { const static int stringSize = 512; TypeInfoVec().swap(_typeInfo); SQLRETURN rc; SQLHSTMT hstmt = SQL_NULL_HSTMT; rc = SQLAllocHandle(SQL_HANDLE_STMT, *_pHDBC, &hstmt); if (!SQL_SUCCEEDED(rc)) throw StatementException(hstmt, "SQLGetData()"); rc = SQLGetTypeInfo(hstmt, SQL_ALL_TYPES); if (SQL_SUCCEEDED(rc)) { while (SQLFetch(hstmt) != SQL_NO_DATA_FOUND) { char typeName[stringSize] = { 0 }; char literalPrefix[stringSize] = { 0 }; char literalSuffix[stringSize] = { 0 }; char createParams[stringSize] = { 0 }; char localTypeName[stringSize] = { 0 }; TypeInfoTup ti("TYPE_NAME", "", "DATA_TYPE", 0, "COLUMN_SIZE", 0, "LITERAL_PREFIX", "", "LITERAL_SUFFIX", "", "CREATE_PARAMS", "", "NULLABLE", 0, "CASE_SENSITIVE", 0, "SEARCHABLE", 0, "UNSIGNED_ATTRIBUTE", 0, "FIXED_PREC_SCALE", 0, "AUTO_UNIQUE_VALUE", 0, "LOCAL_TYPE_NAME", "", "MINIMUM_SCALE", 0, "MAXIMUM_SCALE", 0, "SQL_DATA_TYPE", 0, "SQL_DATETIME_SUB", 0, "NUM_PREC_RADIX", 0, "INTERVAL_PRECISION", 0); SQLLEN ind = 0; rc = SQLGetData(hstmt, 1, SQL_C_CHAR, typeName, sizeof(typeName), &ind); ti.set<0>(typeName); rc = SQLGetData(hstmt, 2, SQL_C_SSHORT, &ti.get<1>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 3, SQL_C_SLONG, &ti.get<2>(), sizeof(SQLINTEGER), &ind); rc = SQLGetData(hstmt, 4, SQL_C_CHAR, literalPrefix, sizeof(literalPrefix), &ind); ti.set<3>(literalPrefix); rc = SQLGetData(hstmt, 5, SQL_C_CHAR, literalSuffix, sizeof(literalSuffix), &ind); ti.set<4>(literalSuffix); rc = SQLGetData(hstmt, 6, SQL_C_CHAR, createParams, sizeof(createParams), &ind); ti.set<5>(createParams); rc = SQLGetData(hstmt, 7, SQL_C_SSHORT, &ti.get<6>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 8, SQL_C_SSHORT, &ti.get<7>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 9, SQL_C_SSHORT, &ti.get<8>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 10, SQL_C_SSHORT, &ti.get<9>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 11, SQL_C_SSHORT, &ti.get<10>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 12, SQL_C_SSHORT, &ti.get<11>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 13, SQL_C_CHAR, localTypeName, sizeof(localTypeName), &ind); ti.set<12>(localTypeName); rc = SQLGetData(hstmt, 14, SQL_C_SSHORT, &ti.get<13>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 15, SQL_C_SSHORT, &ti.get<14>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 16, SQL_C_SSHORT, &ti.get<15>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 17, SQL_C_SSHORT, &ti.get<16>(), sizeof(SQLSMALLINT), &ind); rc = SQLGetData(hstmt, 18, SQL_C_SLONG, &ti.get<17>(), sizeof(SQLINTEGER), &ind); rc = SQLGetData(hstmt, 19, SQL_C_SSHORT, &ti.get<18>(), sizeof(SQLSMALLINT), &ind); _typeInfo.push_back(ti); } } SQLFreeHandle(SQL_HANDLE_STMT, hstmt); } }
static SQLRETURN extract_sql_error_rec( EHEAD *head, SQLCHAR *sqlstate, SQLINTEGER rec_number, SQLINTEGER *native_error, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length ) { SQLRETURN ret; if ( sqlstate ) strcpy((char*) sqlstate, "00000" ); if ( rec_number <= head -> sql_diag_head.internal_count ) { ERROR *ptr; SQLCHAR *as1 = NULL; ptr = head -> sql_diag_head.internal_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } as1 = (SQLCHAR*) unicode_to_ansi_alloc( ptr -> msg, SQL_NTS, __get_connection( head )); if ( sqlstate ) { unicode_to_ansi_copy((char*) sqlstate, ptr -> sqlstate, SQL_NTS, __get_connection( head )); } if ( buffer_length < strlen((char*) as1 ) + 1 ) { ret = SQL_SUCCESS_WITH_INFO; } else { ret = SQL_SUCCESS; } if ( message_text && as1 ) { if ( ret == SQL_SUCCESS ) { strcpy((char*) message_text, (char*) as1 ); } else { memcpy( message_text, as1, buffer_length ); message_text[ buffer_length - 1 ] = '\0'; } } if ( text_length && as1 ) { *text_length = strlen((char*) as1 ); } if ( native_error ) { *native_error = ptr -> native_error; } /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) __map_error_state( (char*) sqlstate, __get_version( head )); if ( as1 ) { free( as1 ); } return ret; } else if ( !__is_env( head ) && __get_connection( head ) -> state != STATE_C2 ) { ERROR *ptr; SQLCHAR *as1 = NULL; SQLWCHAR *s1 = NULL, *s2 = NULL; if ( rec_number <= head -> sql_diag_head.internal_count + head -> sql_diag_head.error_count ) { rec_number -= head -> sql_diag_head.internal_count; } else { rec_number -= ( head -> sql_diag_head.internal_count + head -> sql_diag_head.error_count ); } s1 = malloc( sizeof( SQLWCHAR ) * ( 6 + 1 )); if ( buffer_length > 0 ) { s2 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 )); } if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGRECW( __get_connection( head ))) { ret = SQLGETDIAGRECW( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, s1, native_error, s2, buffer_length, text_length ); /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) { if ( sqlstate ) { unicode_to_ansi_copy((char*) sqlstate, s1, SQL_NTS, __get_connection( head )); __map_error_state((char*) sqlstate, __get_version( head )); } if ( message_text ) { unicode_to_ansi_copy((char*) message_text, s2, SQL_NTS, __get_connection( head )); } } } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGREC( __get_connection( head ))) { ret = SQLGETDIAGREC( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, sqlstate, native_error, message_text, buffer_length, text_length ); /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) __map_error_state((char*) sqlstate, __get_version( head )); } else { SQLCHAR *as1 = NULL; ptr = head -> sql_diag_head.error_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } as1 = (SQLCHAR*) unicode_to_ansi_alloc( ptr -> msg, SQL_NTS, __get_connection( head )); if ( sqlstate ) { unicode_to_ansi_copy((char*) sqlstate, ptr -> sqlstate, SQL_NTS, __get_connection( head )); } if ( as1 && buffer_length < strlen((char*) as1 ) + 1 ) { ret = SQL_SUCCESS_WITH_INFO; } else { ret = SQL_SUCCESS; } if ( message_text && as1 ) { if ( ret == SQL_SUCCESS ) { strcpy((char*) message_text,(char*) as1 ); } else { memcpy( message_text, as1, buffer_length ); message_text[ buffer_length - 1 ] = '\0'; } } if ( text_length && as1 ) { *text_length = strlen((char*) as1 ); } if ( native_error ) { *native_error = ptr -> native_error; } /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) __map_error_state((char*) sqlstate, __get_version( head )); if ( as1 ) { free( as1 ); } } if ( s1 ) free( s1 ); if ( s2 ) free( s2 ); return ret; } else { return SQL_NO_DATA; } }
int main(int argc, char **argv) { SQLRETURN rc; HSTMT hstmt = SQL_NULL_HSTMT; char param1[20] = { 1, 2, 3, 4, 5, 6, 7, 8 }; SQLLEN cbParam1; SQLSMALLINT colcount; SQLSMALLINT dataType; SQLULEN paramSize; SQLSMALLINT decDigits; SQLSMALLINT nullable; test_connect(); rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt); if (!SQL_SUCCEEDED(rc)) { print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn); exit(1); } /**** Query with a bytea param ****/ /* Prepare a statement */ rc = SQLPrepare(hstmt, (SQLCHAR *) "SELECT id, t FROM byteatab WHERE t = ?", SQL_NTS); CHECK_STMT_RESULT(rc, "SQLPrepare failed", hstmt); /* bind param */ cbParam1 = 8; rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, /* value type */ SQL_BINARY, /* param type */ 20, /* column size */ 0, /* dec digits */ param1, /* param value ptr */ 0, /* buffer len */ &cbParam1 /* StrLen_or_IndPtr */); CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt); /* Test SQLNumResultCols, called before SQLExecute() */ rc = SQLNumResultCols(hstmt, &colcount); CHECK_STMT_RESULT(rc, "SQLNumResultCols failed", hstmt); printf("# of result cols: %d\n", colcount); /* Execute */ rc = SQLExecute(hstmt); CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt); /* Fetch result */ print_result(hstmt); rc = SQLFreeStmt(hstmt, SQL_CLOSE); CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); /*** Test SQLBindParameter with SQLExecDirect ***/ printf("\nTesting SQLBindParameter with SQLExecDirect...\n"); /* bind param */ strcpy(param1, "bar"); cbParam1 = SQL_NTS; rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, /* value type */ SQL_CHAR, /* param type */ 20, /* column size */ 0, /* dec digits */ param1, /* param value ptr */ 0, /* buffer len */ &cbParam1 /* StrLen_or_IndPtr */); CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt); rc = SQLExecDirect(hstmt, (SQLCHAR *) "SELECT 'foo' UNION ALL SELECT ?", SQL_NTS); CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); print_result(hstmt); rc = SQLFreeStmt(hstmt, SQL_CLOSE); CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); /*** Test SQLDescribeParam ***/ printf("\nTesting SQLDescribeParam...\n"); rc = SQLFreeStmt(hstmt, SQL_RESET_PARAMS); CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); /* Prepare a statement */ rc = SQLPrepare(hstmt, (SQLCHAR *) "SELECT id, t FROM testtab1 WHERE id = ?", SQL_NTS); CHECK_STMT_RESULT(rc, "SQLPrepare failed", hstmt); rc = SQLDescribeParam(hstmt, 1, &dataType, ¶mSize, &decDigits, &nullable); CHECK_STMT_RESULT(rc, "SQLDescribeParams failed", hstmt); printf("Param 1: type %s; size %u; dec digits %d; %s\n", datatype_str(dataType), (unsigned int) paramSize, decDigits, nullable_str(nullable)); /* bind param */ strcpy(param1, "3"); cbParam1 = SQL_NTS; rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, /* value type */ SQL_CHAR, /* param type */ 20, /* column size */ 0, /* dec digits */ param1, /* param value ptr */ 0, /* buffer len */ &cbParam1 /* StrLen_or_IndPtr */); CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt); /* Test SQLNumResultCols, called before SQLExecute() */ rc = SQLNumResultCols(hstmt, &colcount); CHECK_STMT_RESULT(rc, "SQLNumResultCols failed", hstmt); printf("# of result cols: %d\n", colcount); /* Execute */ rc = SQLExecute(hstmt); CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt); /* Fetch result */ print_result(hstmt); rc = SQLFreeStmt(hstmt, SQL_CLOSE); CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); /* Clean up */ test_disconnect(); return 0; }
bool OdbcConnection::Connect() { if (m_szDSN.empty()) return false; FastGuard lock(m_lock); tstring szConn = _T("DSN=") + m_szDSN + _T(";"); // Reconnect if we need to. if (isConnected()) Disconnect(); // Allocate enviroment handle if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_envHandle))) { ReportSQLError(SQL_HANDLE_ENV, m_envHandle, _T("SQLAllocHandle"), _T("Unable to allocate environment handle.")); goto error_handler; } // Request ODBC3 support if (!SQL_SUCCEEDED(SQLSetEnvAttr(m_envHandle, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0))) { ReportSQLError(SQL_HANDLE_ENV, m_envHandle, _T("SQLSetEnvAttr"), _T("Unable to set environment attribute (SQL_ATTR_ODBC_VERSION).")); goto error_handler; } // Allocate the connection handle if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_DBC, m_envHandle, &m_connHandle))) { ReportSQLError(SQL_HANDLE_ENV, m_envHandle, _T("SQLAllocHandle"), _T("Unable to allocate connection handle.")); goto error_handler; } if (m_szUser.length()) { szConn += _T("UID=") + m_szUser + _T(";"); if (m_szPass.length()) szConn += _T("PWD=") + m_szPass + _T(";"); } // Enable multiple active result sets if (m_bMarsEnabled) { if (!SQL_SUCCEEDED(SQLSetConnectAttr(m_connHandle, SQL_COPT_SS_MARS_ENABLED, SQL_MARS_ENABLED_YES, SQL_IS_UINTEGER))) { printf("** WARNING **\n\n"); printf("Attempted to used MARS (Multiple Active Result Sets), but this\n"); printf("feature is not supported by your ODBC driver or SQL Server version.\n\n"); printf("To benefit from MARS, you need to be using at least SQL Server 2005, and at\n"); printf("least the 'SQL Native Client' ODBC driver (as opposed to the vastly outdated\n'SQL Server' driver).\n\n"); printf("Continuing to connect without MARS.\n\n"); m_bMarsEnabled = false; } // NOTE: We can enable MARS via specifying the following, but we are unable to detect if it's supported this way. // szConn += _T("MARS_Connection=yes;"); } if (!SQL_SUCCEEDED(SQLDriverConnect(m_connHandle, SQL_NULL_HANDLE, (SQLTCHAR *)szConn.c_str(), SQL_NTS, 0, 0, 0, 0))) { ReportSQLError(SQL_HANDLE_DBC, m_connHandle, _T("SQLDriverConnect"), _T("Unable to establish connection.")); goto error_handler; } for (auto itr = m_commandSet.begin(); itr != m_commandSet.end(); itr++) (*itr)->SetConnectionHandle(m_connHandle); return true; error_handler: ResetHandles(); return false; }
/*! * \brief Gets a partial result set, fetch rows from a result * * Gets a partial result set, fetch a number of rows from a databae result. * This function initialize the given result structure on the first run, and * fetches the nrows number of rows. On subsequenting runs, it uses the * existing result and fetches more rows, until it reaches the end of the * result set. Because of this the result needs to be null in the first * invocation of the function. If the number of wanted rows is zero, the * function returns anything with a result of zero. * \param _h structure representing the database connection * \param _r pointer to a structure representing the result * \param nrows number of fetched rows * \return return zero on success, negative value on failure */ int db_unixodbc_fetch_result(const db1_con_t* _h, db1_res_t** _r, const int nrows) { int row_n = 0, i = 0, ret = 0, len; SQLSMALLINT columns; list* rows = NULL; list* rowstart = NULL; strn* temp_row = NULL; if ((!_h) || (!_r) || nrows < 0) { LM_ERR("invalid parameter value\n"); return -1; } /* exit if the fetch count is zero */ if (nrows == 0) { if (*_r) db_free_result(*_r); *_r = 0; return 0; } /* On the first fetch for a query, allocate structures and get columns */ if(*_r == NULL) { /* Allocate a new result structure */ *_r = db_new_result(); LM_DBG("just allocated a new db result structure"); if (*_r == NULL) { LM_ERR("no memory left\n"); return -2; } /* Get columns names and count */ if (db_unixodbc_get_columns(_h, *_r) < 0) { LM_ERR("getting column names failed\n"); db_free_columns(*_r); return -2; } /* On subsequent fetch attempts, reuse already allocated structures */ } else { LM_DBG("db result structure already exist, reusing\n"); /* free old rows */ if(RES_ROWS(*_r) != NULL) db_free_rows(*_r); RES_ROWS(*_r) = 0; RES_ROW_N(*_r) = 0; } SQLNumResultCols(CON_RESULT(_h), (SQLSMALLINT *)&columns); /* Now fetch nrows at most */ len = sizeof(db_row_t) * nrows; RES_ROWS(*_r) = (struct db_row*)pkg_malloc(len); if (!RES_ROWS(*_r)) { LM_ERR("no memory left\n"); return -5; } LM_DBG("allocated %d bytes for RES_ROWS at %p\n", len, RES_ROWS(*_r)); LM_DBG("Now fetching %i rows at most\n", nrows); while(SQL_SUCCEEDED(ret = SQLFetch(CON_RESULT(_h)))) { /* Allocate a temporary row */ temp_row = db_unixodbc_new_cellrow(columns); if (!temp_row) { LM_ERR("no private memory left\n"); pkg_free(RES_ROWS(*_r)); pkg_free(*_r); *_r = 0; return -1; } LM_DBG("fetching %d columns for row %d...\n",columns, row_n); for(i=0; i < columns; i++) { LM_DBG("fetching column %d\n",i); if (!db_unixodbc_load_cell(_h, i+1, temp_row + i, RES_TYPES(*_r)[i])) { pkg_free(RES_ROWS(*_r)); db_unixodbc_free_cellrow(columns, temp_row); pkg_free(*_r); *_r = 0; return -5; } } LM_DBG("got temp_row at %p\n", temp_row); if (db_unixodbc_list_insert(&rowstart, &rows, columns, temp_row) < 0) { LM_ERR("SQL result row insert failed\n"); pkg_free(RES_ROWS(*_r)); db_unixodbc_free_cellrow(columns, temp_row); pkg_free(*_r); *_r = 0; return -5; } /* Free temporary row data */ LM_DBG("freeing temp_row at %p\n", temp_row); db_unixodbc_free_cellrow(columns, temp_row); temp_row = NULL; row_n++; if (row_n == nrows) { break; } } CON_ROW(_h) = NULL; RES_ROW_N(*_r) = row_n; if (!row_n) { LM_DBG("no more rows to process for db fetch"); pkg_free(RES_ROWS(*_r)); RES_ROWS(*_r) = 0; return 0; } /* Convert rows to internal format */ memset(RES_ROWS(*_r), 0, len); i = 0; rows = rowstart; while(rows) { LM_DBG("converting row #%d\n", i); CON_ROW(_h) = rows->data; if (!CON_ROW(_h)) { LM_ERR("string null\n"); RES_ROW_N(*_r) = row_n; db_free_rows(*_r); return -3; } if (db_unixodbc_convert_row(_h, *_r, &(RES_ROWS(*_r)[i]), rows->lengths) < 0) { LM_ERR("converting fetched row #%d failed\n", i); RES_ROW_N(*_r) = i; db_free_rows(*_r); return -4; } i++; rows = rows->next; } db_unixodbc_list_destroy(rowstart); /* update the total number of rows processed */ RES_LAST_ROW(*_r) += row_n; LM_DBG("fetch from db processed %d rows so far\n", RES_LAST_ROW(*_r)); return 0; }
int FetchTest(SQLHANDLE env, SQLHANDLE dbc, SQLHANDLE stmt) { int ret; SQLCHAR szSchema[STR_LEN]; SQLCHAR szCatalog[STR_LEN]; SQLCHAR szColumnName[STR_LEN]; SQLCHAR szTableName[STR_LEN]; SQLCHAR szTypeName[STR_LEN]; SQLCHAR szRemarks[REM_LEN]; SQLCHAR szColumnDefault[STR_LEN]; SQLCHAR szIsNullable[STR_LEN]; SQLINTEGER ColumnSize; SQLINTEGER BufferLength; SQLINTEGER CharOctetLength; SQLINTEGER OrdinalPosition; SQLSMALLINT DataType; SQLSMALLINT DecimalDigits; SQLSMALLINT NumPrecRadix; SQLSMALLINT Nullable; SQLSMALLINT SQLDataType; SQLSMALLINT DatetimeSubtypeCode; ret = SQLColumns(stmt, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"T1", SQL_NTS, NULL, 0); checkrc(ret,__LINE__); short totalFields = 0 ; ret = SQLNumResultCols (stmt, &totalFields); checkrc(ret,__LINE__); printf( "No of columns in resultset = %d\n",totalFields); SQLBindCol(stmt, 1, SQL_C_CHAR, szCatalog, STR_LEN,NULL); SQLBindCol(stmt, 2, SQL_C_CHAR, szSchema, STR_LEN, NULL); SQLBindCol(stmt, 3, SQL_C_CHAR, szTableName, STR_LEN,NULL); SQLBindCol(stmt, 4, SQL_C_CHAR, szColumnName, STR_LEN, NULL); SQLBindCol(stmt, 5, SQL_C_SSHORT, &DataType, 0, NULL); SQLBindCol(stmt, 6, SQL_C_CHAR, szTypeName, STR_LEN, NULL); SQLBindCol(stmt, 7, SQL_C_SLONG, &ColumnSize, 0, NULL); SQLBindCol(stmt, 8, SQL_C_SLONG, &BufferLength, 0, NULL); SQLBindCol(stmt, 9, SQL_C_SSHORT, &DecimalDigits, 0, NULL); SQLBindCol(stmt, 10, SQL_C_SSHORT, &NumPrecRadix, 0, NULL); SQLBindCol(stmt, 11, SQL_C_SSHORT, &Nullable, 0, NULL); SQLBindCol(stmt, 12, SQL_C_CHAR, szRemarks, REM_LEN, NULL); SQLBindCol(stmt, 13, SQL_C_CHAR, szColumnDefault, STR_LEN, NULL); SQLBindCol(stmt, 14, SQL_C_SSHORT, &SQLDataType, 0, NULL); SQLBindCol(stmt, 15, SQL_C_SSHORT, &DatetimeSubtypeCode, 0,NULL); SQLBindCol(stmt, 16, SQL_C_SLONG, &CharOctetLength, 0, NULL); SQLBindCol(stmt, 17, SQL_C_SLONG, &OrdinalPosition, 0, NULL); SQLBindCol(stmt, 18, SQL_C_CHAR, szIsNullable, STR_LEN, NULL); while(SQL_SUCCEEDED(ret = SQLFetch(stmt))) { printf("szCatalog =%s \t szSchema=%s \t szTableName=%s \t szColumnName= %s \t DataType = %d ColumnSize = %d Nullable =%d szRemarks = %s, OrdinalPosition =%d szIsNullable =%s\n ",szCatalog,szSchema,szTableName,szColumnName,DataType,ColumnSize,Nullable,szRemarks,OrdinalPosition,szIsNullable); } ret = SQLCloseCursor(stmt); checkrc(ret,__LINE__); ret = SQLTransact(env,dbc,SQL_COMMIT); checkrc(ret,__LINE__); return 0; }
SQLRETURN MADB_DaeStmt(MADB_Stmt *Stmt, SQLUSMALLINT Operation) { char *TableName= MADB_GetTableName(Stmt); char *CatalogName= MADB_GetCatalogName(Stmt); MADB_DynString DynStmt; MADB_CLEAR_ERROR(&Stmt->Error); memset(&DynStmt, 0, sizeof(MADB_DynString)); if (Stmt->DaeStmt) Stmt->Methods->StmtFree(Stmt->DaeStmt, SQL_DROP); Stmt->DaeStmt= NULL; if (!SQL_SUCCEEDED(MA_SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE)Stmt->Connection, (SQLHANDLE *)&Stmt->DaeStmt))) { MADB_CopyError(&Stmt->Error, &Stmt->Connection->Error); goto end; } switch(Operation) { case SQL_ADD: if (MADB_InitDynamicString(&DynStmt, "INSERT INTO ", 1024, 1024) || MADB_DynStrAppendQuoted(&DynStmt, CatalogName) || MADB_DynstrAppend(&DynStmt, ".") || MADB_DynStrAppendQuoted(&DynStmt, TableName)|| MADB_DynStrUpdateSet(Stmt, &DynStmt)) { MADB_DynstrFree(&DynStmt); return Stmt->Error.ReturnValue; } Stmt->DataExecutionType= MADB_DAE_ADD; break; case SQL_DELETE: if (MADB_InitDynamicString(&DynStmt, "DELETE FROM ", 1024, 1024) || MADB_DynStrAppendQuoted(&DynStmt, CatalogName) || MADB_DynstrAppend(&DynStmt, ".") || MADB_DynStrAppendQuoted(&DynStmt, TableName) || MADB_DynStrGetWhere(Stmt, &DynStmt, TableName, FALSE)) { MADB_DynstrFree(&DynStmt); return Stmt->Error.ReturnValue; } Stmt->DataExecutionType= MADB_DAE_DELETE; break; case SQL_UPDATE: if (MADB_InitDynamicString(&DynStmt, "UPDATE ", 1024, 1024) || MADB_DynStrAppendQuoted(&DynStmt, CatalogName) || MADB_DynstrAppend(&DynStmt, ".") || MADB_DynStrAppendQuoted(&DynStmt, TableName)|| MADB_DynStrUpdateSet(Stmt, &DynStmt)|| MADB_DynStrGetWhere(Stmt, &DynStmt, TableName, FALSE)) { MADB_DynstrFree(&DynStmt); return Stmt->Error.ReturnValue; } Stmt->DataExecutionType= MADB_DAE_UPDATE; break; } if (!SQL_SUCCEEDED(Stmt->DaeStmt->Methods->Prepare(Stmt->DaeStmt, (SQLCHAR *)DynStmt.str, SQL_NTS, FALSE))) { MADB_CopyError(&Stmt->Error, &Stmt->DaeStmt->Error); Stmt->Methods->StmtFree(Stmt->DaeStmt, SQL_DROP); } end: MADB_DynstrFree(&DynStmt); return Stmt->Error.ReturnValue; }
SQLRETURN SQL_API SQLGetConnectAttrW(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER BufferLength, SQLINTEGER *StringLengthPtr) { ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle; SQLRETURN rc; SQLPOINTER ptr; SQLINTEGER n; #ifdef ODBCDEBUG ODBCLOG("SQLGetConnectAttrW " PTRFMT " %s " PTRFMT " %d " PTRFMT "\n", PTRFMTCAST ConnectionHandle, translateConnectAttribute(Attribute), PTRFMTCAST ValuePtr, (int) BufferLength, PTRFMTCAST StringLengthPtr); #endif if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); switch (Attribute) { /* all string attributes */ case SQL_ATTR_CURRENT_CATALOG: ptr = malloc(BufferLength); if (ptr == NULL) { /* Memory allocation error */ addDbcError(dbc, "HY001", NULL, 0); return SQL_ERROR; } break; default: ptr = ValuePtr; break; } rc = MNDBGetConnectAttr(dbc, Attribute, ptr, BufferLength, &n); if (ptr != ValuePtr) { if (rc == SQL_SUCCESS_WITH_INFO) { clearDbcErrors(dbc); free(ptr); ptr = malloc(++n); /* add one for NULL byte */ if (ptr == NULL) { /* Memory allocation error */ addDbcError(dbc, "HY001", NULL, 0); return SQL_ERROR; } rc = MNDBGetConnectAttr(dbc, Attribute, ptr, n, &n); } if (SQL_SUCCEEDED(rc)) { SQLSMALLINT nn = (SQLSMALLINT) n; fixWcharOut(rc, ptr, nn, ValuePtr, BufferLength, StringLengthPtr, 2, addDbcError, dbc); } free(ptr); } else if (StringLengthPtr) *StringLengthPtr = n; return rc; }
static PyObject* CnxnInfo_New(Connection* cnxn) { CnxnInfo* p = PyObject_NEW(CnxnInfo, &CnxnInfoType); if (!p) return 0; Object info((PyObject*)p); // set defaults p->odbc_major = 3; p->odbc_minor = 50; p->supports_describeparam = false; p->datetime_precision = 19; // default: "yyyy-mm-dd hh:mm:ss" // WARNING: The GIL lock is released for the *entire* function here. Do not touch any objects, call Python APIs, // etc. We are simply making ODBC calls and setting atomic values (ints & chars). Also, make sure the lock gets // released -- do not add an early exit. SQLRETURN ret; Py_BEGIN_ALLOW_THREADS char szVer[20]; SQLSMALLINT cch = 0; ret = SQLGetInfo(cnxn->hdbc, SQL_DRIVER_ODBC_VER, szVer, _countof(szVer), &cch); if (SQL_SUCCEEDED(ret)) { char* dot = strchr(szVer, '.'); if (dot) { *dot = '\0'; p->odbc_major=(char)atoi(szVer); p->odbc_minor=(char)atoi(dot + 1); } } char szYN[2]; ret = SQLGetInfo(cnxn->hdbc, SQL_DESCRIBE_PARAMETER, szYN, _countof(szYN), &cch); if (SQL_SUCCEEDED(ret)) { p->supports_describeparam = szYN[0] == 'Y'; } // What is the datetime precision? This unfortunately requires a cursor (HSTMT). HSTMT hstmt = 0; if (SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, cnxn->hdbc, &hstmt))) { if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_TYPE_TIMESTAMP)) && SQL_SUCCEEDED(SQLFetch(hstmt))) { SQLINTEGER columnsize; if (SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, sizeof(columnsize), 0))) { p->datetime_precision = columnsize; } } SQLFreeStmt(hstmt, SQL_CLOSE); } Py_END_ALLOW_THREADS // WARNING: Released the lock now. return info.Detach(); }
SQLRETURN __SQLFreeHandle( SQLSMALLINT handle_type, SQLHANDLE handle ) { switch( handle_type ) { case SQL_HANDLE_ENV: { DMHENV environment = (DMHENV)handle; /* * check environment */ if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( environment ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); /* * check states */ if ( environment -> state != STATE_E1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &environment -> error, ERROR_HY010, NULL, environment -> requested_version ); return function_return( SQL_HANDLE_ENV, environment, SQL_ERROR ); } thread_release( SQL_HANDLE_ENV, environment ); __release_env( environment ); return SQL_SUCCESS; } break; case SQL_HANDLE_DBC: { DMHDBC connection = (DMHDBC)handle; DMHENV environment; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); environment = connection -> environment; if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); /* * check states */ if ( connection -> state != STATE_C2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return( SQL_HANDLE_ENV, environment, SQL_ERROR ); } environment -> connection_count --; if ( environment -> connection_count == 0 ) { environment -> state = STATE_E1; } environment = connection -> environment; __release_attr_str( &connection -> env_attribute ); __release_attr_str( &connection -> dbc_attribute ); __release_attr_str( &connection -> stmt_attribute ); __disconnect_part_one( connection ); __release_dbc( connection ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tExit:[SQL_SUCCESS]" ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) uodbc_update_stats(environment->sh, UODBC_STATS_TYPE_HDBC, (void *)-1); #endif thread_release( SQL_HANDLE_ENV, environment ); return SQL_SUCCESS; } break; case SQL_HANDLE_STMT: { DMHSTMT statement = (DMHSTMT)handle; DMHDBC connection; SQLRETURN ret; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); connection = statement -> connection; if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( !CHECK_SQLFREEHANDLE( statement -> connection )) { if ( !CHECK_SQLFREESTMT( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else { ret = SQLFREESTMT( statement -> connection, statement -> driver_stmt, SQL_DROP ); } } else { ret = SQLFREEHANDLE( statement -> connection, handle_type, statement -> driver_stmt ); } if ( SQL_SUCCEEDED( ret )) { /* * break any association */ if ( statement -> ard ) { statement -> ard -> associated_with = NULL; } if ( statement -> apd ) { statement -> apd -> associated_with = NULL; } /* * release the implicit descriptors, * this matches the tests in SQLAllocHandle */ if (( statement -> connection -> driver_act_ver == 3 && CHECK_SQLGETSTMTATTR( connection )) || CHECK_SQLGETSTMTATTRW( connection )) { if ( statement -> implicit_ard ) __release_desc( statement -> implicit_ard ); if ( statement -> implicit_apd ) __release_desc( statement -> implicit_apd ); if ( statement -> implicit_ird ) __release_desc( statement -> implicit_ird ); if ( statement -> implicit_ipd ) __release_desc( statement -> implicit_ipd ); } statement -> connection -> statement_count --; thread_release( SQL_HANDLE_STMT, statement ); #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) uodbc_update_stats(connection->environment->sh, UODBC_STATS_TYPE_HSTMT, (void *)-1); #endif __release_stmt( statement ); } else { thread_release( SQL_HANDLE_STMT, statement ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[SQL_SUCCESS]" ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( IGNORE_THREAD, connection, ret ); } break; case SQL_HANDLE_DESC: { DMHDESC descriptor = (DMHDESC)handle; DMHDBC connection; SQLRETURN ret; /* * check descriptor */ if ( !__validate_desc( descriptor )) { return SQL_INVALID_HANDLE; } function_entry( descriptor ); connection = descriptor -> connection; if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } if ( descriptor -> implicit ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY017" ); __post_internal_error( &descriptor -> error, ERROR_HY017, NULL, connection -> environment -> requested_version ); return function_return( IGNORE_THREAD, descriptor, SQL_ERROR ); } thread_protect( SQL_HANDLE_DESC, descriptor ); if ( !CHECK_SQLFREEHANDLE( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } else { ret = SQLFREEHANDLE( connection, handle_type, descriptor -> driver_desc ); } /* * check status of statements associated with this descriptor */ if( __check_stmt_from_desc( descriptor, STATE_S8 ) || __check_stmt_from_desc( descriptor, STATE_S9 ) || __check_stmt_from_desc( descriptor, STATE_S10 ) || __check_stmt_from_desc( descriptor, STATE_S11 ) || __check_stmt_from_desc( descriptor, STATE_S12 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } thread_release( SQL_HANDLE_DESC, descriptor ); __release_desc( descriptor ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[SQL_SUCCESS]" ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) uodbc_update_stats(connection->environment->sh, UODBC_STATS_TYPE_HDESC, (void *)-1); #endif return function_return( IGNORE_THREAD, connection, SQL_SUCCESS ); } break; default: /* * there is nothing to report a error on */ return SQL_ERROR; } }
int wmain(int argc, wchar_t* argv[], wchar_t* arge[]) { std::locale::global(std::locale("", std::locale::ctype)); SQLRETURN res = SQL_SUCCESS; bool bError = true; std::wstring strErr(L""); SQLSMALLINT errHandleType = 0; SQLHANDLE errHandle = SQL_NULL_HANDLE; SQLHENV henv = SQL_NULL_HANDLE; SQLHDBC hdbc = SQL_NULL_HANDLE; SQLHSTMT hstmt = SQL_NULL_HANDLE; bool bConnect = false; // 環境ハンドルの作成&設定 res = ::SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); if(!SQL_SUCCEEDED(res)){strErr = L"環境ハンドル作成"; errHandleType = SQL_HANDLE_ENV; errHandle = SQL_NULL_HANDLE; goto end;} res = ::SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>(SQL_OV_ODBC3), 0); if(!SQL_SUCCEEDED(res)){strErr = L"環境ハンドル設定"; errHandleType = SQL_HANDLE_ENV; errHandle = henv; goto end;} // 接続ハンドルの作成 res = ::SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); if(!SQL_SUCCEEDED(res)){strErr = L"接続ハンドル作成"; errHandleType = SQL_HANDLE_ENV; errHandle = henv; goto end;} // ODBCドライバへ接続 res = ::SQLDriverConnect(hdbc, NULL, L"DRIVER={SQL Server Native Client 10.0};SERVER=(local);Trusted_Connection=yes;Database=TestDB", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if(!SQL_SUCCEEDED(res)){strErr = L"接続"; errHandleType = SQL_HANDLE_DBC; errHandle = hdbc; goto end;} bConnect = true; std::wcout << L"接続成功" << std::endl; // ステートメントハンドルを作成 res = ::SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); if(!SQL_SUCCEEDED(res)){strErr = L"ステートメントハンドル作成"; errHandleType = SQL_HANDLE_DBC; errHandle = hdbc; goto end;} /* SQLExecute // SQL実行 { // INSERT res = ::SQLPrepareW(hstmt, L"INSERT INTO TestTable(ID, Name, Price) VALUES(?, ?, ?)", SQL_NTS); if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 1 Prepare"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} int ID = 0; SQLLEN nRes_ID = 0; res = ::SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &ID, 0, &nRes_ID); if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 1 BindParam 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} SQLWCHAR Name[21] = {'0'}; SQLLEN nRes_Name = SQL_NTS; res = ::SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WVARCHAR, 20, 0, Name, 0, &nRes_Name); if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 1 BindParam 2"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} int Price = 0; SQLLEN nRes_Price = 0; res = ::SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &Price, 0, &nRes_Price); if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 1 BindParam 3"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} ID = 3; wcscpy_s(Name, L"サンドイッチ"); Price = 200; res = ::SQLExecute(hstmt); if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 1 Execute"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} ID = 4; wcscpy_s(Name, L"カップ麺"); Price = 250; res = ::SQLExecute(hstmt); if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 2 Execute"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} } { // UPDATE res = ::SQLPrepareW(hstmt, L"UPDATE TestTable SET Price=? WHERE Price=?", SQL_NTS); if(!SQL_SUCCEEDED(res)){strErr = L"UPDATE 1 Prepare"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} int Price_After = 0; SQLLEN nRes_PriceA = 0; res = ::SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &Price_After, 0, &nRes_PriceA); if(!SQL_SUCCEEDED(res)){strErr = L"UPDATE 1 BindParam 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} int Price_Before = 0; SQLLEN nRes_PriceB = 0; res = ::SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &Price_Before, 0, &nRes_PriceB); if(!SQL_SUCCEEDED(res)){strErr = L"UPDATE 1 BindParam 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} Price_After = 210; Price_Before = 200; res = ::SQLExecute(hstmt); if(!SQL_SUCCEEDED(res)){strErr = L"UPDATE 1 Execute"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} } { // DELETE res = ::SQLPrepareW(hstmt, L"DELETE FROM TestTable WHERE ID>=?", SQL_NTS); if(!SQL_SUCCEEDED(res)){strErr = L"DELETE 1 Prepare"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} int ID = 0; SQLLEN nRes_ID = 0; res = ::SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &ID, 0, &nRes_ID); if(!SQL_SUCCEEDED(res)){strErr = L"DELETE 1 BindParam 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} ID = 3; res = ::SQLExecute(hstmt); if(!SQL_SUCCEEDED(res)){strErr = L"DELETE 1 Execute"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} } { // SELECT res = ::SQLPrepareW(hstmt, L"SELECT * FROM TestTable WHERE Price>=?", SQL_NTS); if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Prepare"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} int Price = 0; SQLLEN nRes_Price = 0; res = ::SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &Price, 0, &nRes_Price); if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 BindParam 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} Price = 100; res = ::SQLExecute(hstmt); if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Execute"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} { std::wcout << L"SQL実行 SELECT 1" << std::endl; SQLINTEGER id = 0; SQLWCHAR name[20 + 1] ={L'\0'}; SQLINTEGER price = 0; SQLLEN len1 = 0; SQLLEN len2 = 0; SQLLEN len3 = 0; res = ::SQLBindCol(hstmt, 1, SQL_C_SLONG, &id, sizeof(id), &len1); if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} res = ::SQLBindCol(hstmt, 2, SQL_C_WCHAR, &name, sizeof(name), &len2); if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 2"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} res = ::SQLBindCol(hstmt, 3, SQL_C_SLONG, &price, sizeof(price), &len3); if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 3"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} while(SQL_SUCCEEDED(::SQLFetch(hstmt))) std::wcout << id << L", " << name << L", " << price << L" : (" << len1 << L", " << len2 << L", " << len3 << L')' << std::endl; } res = ::SQLCloseCursor(hstmt); if(!SQL_SUCCEEDED(res)){strErr = L"Close カーソル SELECT 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} } */ /* SQLExecDirect // INSERT res = ::SQLExecDirect(hstmt, L"INSERT INTO TestTable(ID, Name, Price) VALUES(3, 'サンドイッチ', 200)", SQL_NTS); if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 INSERT 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} { SQLLEN cnt = 0; res = ::SQLRowCount(hstmt, &cnt); if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 INSERT 1 結果列数取得"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} std::wcout << L"SQL実行 INSERT 1 : " << cnt << L" 行 処理されました。" << std::endl; } // UPDATE res = ::SQLExecDirect(hstmt, L"UPDATE TestTable SET Price=250 WHERE Price=200", SQL_NTS); if(res == SQL_NO_DATA){std::wcout << L"SQL実行 UPDATE 1 : データがありませんでした。" << std::endl;} else if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 UPDATE 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} else { SQLLEN cnt = 0; res = ::SQLRowCount(hstmt, &cnt); if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 UPDATE 1 結果列数取得"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} std::wcout << L"SQL実行 UPDATE 1 : " << cnt << L" 行 処理されました。" << std::endl; } // DELETE res = ::SQLExecDirect(hstmt, L"DELETE FROM TestTable WHERE Price=250", SQL_NTS); if(res == SQL_NO_DATA){std::wcout << L"SQL実行 DELETE 1 : データがありませんでした。" << std::endl;} else if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 DELETE 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} else { SQLLEN cnt = 0; res = ::SQLRowCount(hstmt, &cnt); if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 DELETE 1 結果列数取得"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} std::wcout << L"SQL実行 DELETE 1 : " << cnt << L" 行 処理されました。" << std::endl; } // SELECT res = ::SQLExecDirect(hstmt, L"SELECT * FROM TestTable", SQL_NTS); if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 SELECT 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} { std::wcout << L"SQL実行 SELECT 1" << std::endl; SQLINTEGER id = 0; SQLWCHAR name[20 + 1] ={L'\0'}; SQLINTEGER price = 0; SQLLEN len1 = 0; SQLLEN len2 = 0; SQLLEN len3 = 0; res = ::SQLBindCol(hstmt, 1, SQL_C_SLONG, &id, sizeof(id), &len1); if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} res = ::SQLBindCol(hstmt, 2, SQL_C_WCHAR, &name, sizeof(name), &len2); if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 2"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} res = ::SQLBindCol(hstmt, 3, SQL_C_SLONG, &price, sizeof(price), &len3); if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 3"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} while(SQL_SUCCEEDED(::SQLFetch(hstmt))) std::wcout << id << L", " << name << L", " << price << L" : (" << len1 << L", " << len2 << L", " << len3 << L')' << std::endl; } res = ::SQLCloseCursor(hstmt); if(!SQL_SUCCEEDED(res)){strErr = L"Close カーソル SELECT 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} */ { // Auto Commit Off res = ::SQLSetConnectAttrW(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_UINTEGER); if(!SQL_SUCCEEDED(res)){strErr = L"Connect属性セット 1"; errHandleType = SQL_HANDLE_DBC; errHandle = hdbc; goto end;} // Rollback if(!TransactionSequence(hstmt)){strErr = L"TranSeq 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} res = ::SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_ROLLBACK); if(!SQL_SUCCEEDED(res)){strErr = L"Rollback"; errHandleType = SQL_HANDLE_DBC; errHandle = hdbc; goto end;} // Commit if(!TransactionSequence(hstmt)){strErr = L"TranSeq 2"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} res = ::SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT); if(!SQL_SUCCEEDED(res)){strErr = L"Commit"; errHandleType = SQL_HANDLE_DBC; errHandle = hdbc; goto end;} // Cleanup if(!CleanupTranSeq(hstmt)){strErr = L"CleanTranSeq 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} res = ::SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT); if(!SQL_SUCCEEDED(res)){strErr = L"Commit Cleanup 1"; errHandleType = SQL_HANDLE_DBC; errHandle = hdbc; goto end;} } { // Auto Commit On res = ::SQLSetConnectAttrW(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER); if(!SQL_SUCCEEDED(res)){strErr = L"Connect属性セット 2"; errHandleType = SQL_HANDLE_DBC; errHandle = hdbc; goto end;} // Rollback Sequence res = ::SQLExecDirect(hstmt, L"BEGIN TRANSACTION", SQL_NTS); if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 BEGIN TRANSACTION 1"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} if(!TransactionSequence(hstmt)){strErr = L"TranSeq 3"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} res = ::SQLExecDirect(hstmt, L"ROLLBACK TRANSACTION", SQL_NTS); if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 ROLLBACK TRANSACTION 2"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} // Commit res = ::SQLExecDirect(hstmt, L"BEGIN TRANSACTION", SQL_NTS); if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 BEGIN TRANSACTION 2"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} if(!TransactionSequence(hstmt)){strErr = L"TranSeq 4"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} res = ::SQLExecDirect(hstmt, L"COMMIT TRANSACTION", SQL_NTS); if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 ROLLBACK TRANSACTION 3"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} // Cleanup if(!CleanupTranSeq(hstmt)){strErr = L"CleanTranSeq 2"; errHandleType = SQL_HANDLE_STMT; errHandle = hstmt; goto end;} } std::wcout << L"SQL実行成功" << std::endl; bError = false; end: if(bError) { SQLWCHAR szState[6] = {L'\0'}; SQLWCHAR szErrorMsg[1024] = {L'\0'}; SQLINTEGER nErrorCode = 0; SQLSMALLINT nSize = 0; ::SQLGetDiagRec(errHandleType, errHandle, 1, szState, &nErrorCode, szErrorMsg, sizeof(szErrorMsg), &nSize); std::wcout << L"エラー(" << strErr << L") State=[" << szState << L"] ErrorMsg[" << szErrorMsg << L"]" << std::endl; } if(hstmt != SQL_NULL_HANDLE) ::SQLFreeHandle(SQL_HANDLE_STMT, hstmt); if(hdbc != SQL_NULL_HANDLE) { if(bConnect) ::SQLDisconnect(hdbc); ::SQLFreeHandle(SQL_HANDLE_DBC, hdbc); } if(henv != SQL_NULL_HANDLE) ::SQLFreeHandle(SQL_HANDLE_ENV, henv); std::wcout << L"終了するには何かキーを押してください。" << std::endl; _getch(); return 0; }
int main(int argc, char **argv) { int rc; HSTMT hstmt = SQL_NULL_HSTMT; int i; SQLINTEGER colvalue; SQLLEN indColvalue; test_connect(); rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt); if (!SQL_SUCCEEDED(rc)) { print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn); exit(1); } /* * Initialize a table with some test data. */ printf("Creating test table pos_update_test\n"); rc = SQLExecDirect(hstmt, (SQLCHAR *) "CREATE TEMPORARY TABLE pos_update_test(i int4, orig int4)", SQL_NTS); CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); rc = SQLExecDirect(hstmt, (SQLCHAR *) "INSERT INTO pos_update_test SELECT g, g FROM generate_series(1, 10) g", SQL_NTS); CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); rc = SQLFreeStmt(hstmt, SQL_CLOSE); CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); printf("Opening a cursor for update, and fetching 10 rows\n"); rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0); CHECK_STMT_RESULT(rc, "SQLSetStmtAttr failed", hstmt); rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_KEYSET_DRIVEN, 0); CHECK_STMT_RESULT(rc, "SQLSetStmtAttr failed", hstmt); rc = SQLBindCol(hstmt, 1, SQL_C_LONG, &colvalue, 0, &indColvalue); CHECK_STMT_RESULT(rc, "SQLBindCol failed", hstmt); rc = SQLExecDirect(hstmt, (SQLCHAR *) "SELECT * FROM pos_update_test ORDER BY orig", SQL_NTS); CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); for (i = 0; i < 5; i++) { rc = SQLFetch(hstmt); if (rc == SQL_NO_DATA) break; if (rc == SQL_SUCCESS) { char buf[40]; int col; SQLLEN ind; for (col = 1; col <= 2; col++) { rc = SQLGetData(hstmt, col, SQL_C_CHAR, buf, sizeof(buf), &ind); if (!SQL_SUCCEEDED(rc)) { print_diag("SQLGetData failed", SQL_HANDLE_STMT, hstmt); exit(1); } if (ind == SQL_NULL_DATA) strcpy(buf, "NULL"); printf("%s%s", (col > 1) ? "\t" : "", buf); } printf("\n"); } else { print_diag("SQLFetch failed", SQL_HANDLE_STMT, hstmt); exit(1); } } /* Do a positioned update and delete */ printf("Updating result set\n"); colvalue += 100; rc = SQLSetPos(hstmt, 1, SQL_UPDATE, SQL_LOCK_NO_CHANGE); CHECK_STMT_RESULT(rc, "SQLSetPos failed", hstmt); rc = SQLFetch(hstmt); CHECK_STMT_RESULT(rc, "SQLFetch failed", hstmt); rc = SQLSetPos(hstmt, 1, SQL_DELETE, SQL_LOCK_NO_CHANGE); CHECK_STMT_RESULT(rc, "SQLSetPos failed", hstmt); rc = SQLFreeStmt(hstmt, SQL_CLOSE); CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); /* See if the update took effect */ rc = SQLExecDirect(hstmt, (SQLCHAR *) "SELECT * FROM pos_update_test ORDER BY orig", SQL_NTS); CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); print_result(hstmt); /* Clean up */ test_disconnect(); return 0; }
static void *db_iodbc_open_int(TABDCA *dca, int mode, const char **sqllines) { struct db_odbc *sql; SQLRETURN ret; SQLCHAR FAR *dsn; SQLCHAR info[256]; SQLSMALLINT colnamelen; SQLSMALLINT nullable; SQLSMALLINT scale; const char *arg; int narg; int i, j; int total; if (libodbc == NULL) { xprintf("No loader for shared ODBC library available\n"); return NULL; } if (h_odbc == NULL) { h_odbc = xdlopen(libodbc); if (h_odbc == NULL) { xprintf("unable to open library %s\n", libodbc); xprintf("%s\n", xerrmsg()); return NULL; } } sql = (struct db_odbc *) xmalloc(sizeof(struct db_odbc)); if (sql == NULL) return NULL; sql->mode = mode; sql->hdbc = NULL; sql->henv = NULL; sql->hstmt = NULL; sql->query = NULL; narg = mpl_tab_num_args(dca); dsn = (SQLCHAR FAR *) mpl_tab_get_arg(dca, 2); /* allocate an environment handle */ ret = dl_SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(sql->henv)); /* set attribute to enable application to run as ODBC 3.0 application */ ret = dl_SQLSetEnvAttr(sql->henv, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0); /* allocate a connection handle */ ret = dl_SQLAllocHandle(SQL_HANDLE_DBC, sql->henv, &(sql->hdbc)); /* connect */ ret = dl_SQLDriverConnect(sql->hdbc, NULL, dsn, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE); if (SQL_SUCCEEDED(ret)) { /* output information about data base connection */ xprintf("Connected to "); dl_SQLGetInfo(sql->hdbc, SQL_DBMS_NAME, (SQLPOINTER)info, sizeof(info), NULL); xprintf("%s ", info); dl_SQLGetInfo(sql->hdbc, SQL_DBMS_VER, (SQLPOINTER)info, sizeof(info), NULL); xprintf("%s - ", info); dl_SQLGetInfo(sql->hdbc, SQL_DATABASE_NAME, (SQLPOINTER)info, sizeof(info), NULL); xprintf("%s\n", info); } else { /* describe error */ xprintf("Failed to connect\n"); extract_error("SQLDriverConnect", sql->hdbc, SQL_HANDLE_DBC); dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); xfree(sql); return NULL; } /* set AUTOCOMMIT on*/ ret = dl_SQLSetConnectAttr(sql->hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0); /* allocate a statement handle */ ret = dl_SQLAllocHandle(SQL_HANDLE_STMT, sql->hdbc, &(sql->hstmt)); /* initialization queries */ for(j = 0; sqllines[j+1] != NULL; j++) { sql->query = (SQLCHAR *) sqllines[j]; xprintf("%s\n", sql->query); ret = dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS); switch (ret) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: case SQL_NO_DATA_FOUND: break; default: xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", sql->query); extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT); dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); dl_SQLDisconnect(sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); xfree(sql); return NULL; } /* commit statement */ dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT); } if ( sql->mode == 'R' ) { sql->nf = mpl_tab_num_flds(dca); for(j = 0; sqllines[j] != NULL; j++) arg = sqllines[j]; total = strlen(arg); if (total > 7 && 0 == strncmp(arg, "SELECT ", 7)) { total = strlen(arg); sql->query = xmalloc( (total+1) * sizeof(char)); strcpy (sql->query, arg); } else { sql->query = db_generate_select_stmt(dca); } xprintf("%s\n", sql->query); if (dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS) != SQL_SUCCESS) { xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", sql->query); extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT); dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); dl_SQLDisconnect(sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); xfree(sql->query); xfree(sql); return NULL; } xfree(sql->query); /* determine number of result columns */ ret = dl_SQLNumResultCols(sql->hstmt, &sql->nresultcols); total = sql->nresultcols; if (total > SQL_FIELD_MAX) { xprintf("db_iodbc_open: Too many fields (> %d) in query.\n" "\"%s\"\n", SQL_FIELD_MAX, sql->query); dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); dl_SQLDisconnect(sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); xfree(sql->query); return NULL; } for (i = 1; i <= total; i++) { /* return a set of attributes for a column */ ret = dl_SQLDescribeCol(sql->hstmt, (SQLSMALLINT) i, sql->colname[i], SQL_FDLEN_MAX, &colnamelen, &(sql->coltype[i]), &(sql->collen[i]), &scale, &nullable); sql->isnumeric[i] = is_numeric(sql->coltype[i]); /* bind columns to program vars, converting all types to CHAR*/ if (sql->isnumeric[i]) { dl_SQLBindCol(sql->hstmt, i, SQL_DOUBLE, sql->data[i], SQL_FDLEN_MAX, &(sql->outlen[i])); } else { dl_SQLBindCol(sql->hstmt, i, SQL_CHAR, sql->data[i], SQL_FDLEN_MAX, &(sql->outlen[i])); } for (j = sql->nf; j >= 1; j--) { if (strcmp(mpl_tab_get_name(dca, j), sql->colname[i]) == 0) break; } sql->ref[i] = j; } } else if ( sql->mode == 'W' ) { for(j = 0; sqllines[j] != NULL; j++) arg = sqllines[j]; if ( NULL != strchr(arg, '?') ) { total = strlen(arg); sql->query = xmalloc( (total+1) * sizeof(char)); strcpy (sql->query, arg); } else { sql->query = db_generate_insert_stmt(dca); } xprintf("%s\n", sql->query); } return sql; }
//************************************************************************* int main() { SQLHENV env; SQLHDBC dbc; SQLHSTMT stmt; SQLRETURN ret; SQLCHAR outstr[1024]; SQLSMALLINT outstrlen; // Aloocate an environment handle ret=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&env); checkrc(ret,__LINE__); //we need odbc3 support SQLSetEnvAttr(env,SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3,0); //ALLOCATE A Connection handle ret = SQLAllocHandle(SQL_HANDLE_DBC,env,&dbc); checkrc(ret,__LINE__); // connect to the DSN mydsn ret = SQLConnect (dbc, (SQLCHAR *) "DSN=mycsql;MODE=csql;SERVER=localhost;PORT=5678;", (SQLSMALLINT) strlen ("DSN=mycsql;MODE=csql;SERVER=localhost;PORT=5678;"), (SQLCHAR *) "root", (SQLSMALLINT) strlen ("root"), (SQLCHAR *) "manager", (SQLSMALLINT) strlen ("")); if(SQL_SUCCEEDED(ret)) { printf("\nConnected to the Data Source..\n"); } else { printf("connection failed\n"); ret = SQLFreeHandle(SQL_HANDLE_DBC,dbc); checkrc(ret,__LINE__); ret = SQLFreeHandle(SQL_HANDLE_ENV,env); checkrc(ret,__LINE__); return 1; } ret = SQLAllocHandle(SQL_HANDLE_STMT,dbc,&stmt); checkrc(ret,__LINE__); SQLCHAR table[100]="CREATE TABLE EMP(EID INT,SALARY INT)"; ret = SQLPrepare(stmt,table,SQL_NTS); checkrc(ret,__LINE__); ret = SQLDisconnect(dbc); checkrc(ret,__LINE__); //AFTER CLOSE THE CONNECTION ,CALL execute ret = SQLExecute(stmt); int rettype = ret; if(ret ) printf("After closing the connection, Execution failed\n"); ret = SQLFreeHandle(SQL_HANDLE_DBC,dbc); checkrc(ret,__LINE__); ret = SQLFreeHandle(SQL_HANDLE_ENV,env); checkrc(ret,__LINE__); if(rettype ==0)return 1; return 0; }
static bool Connect(PyObject* pConnectString, HDBC hdbc, bool fAnsi, long timeout) { // This should have been checked by the global connect function. I(PyString_Check(pConnectString) || PyUnicode_Check(pConnectString)); const int cchMax = 600; if (PySequence_Length(pConnectString) >= cchMax) { PyErr_SetString(PyExc_TypeError, "connection string too long"); return false; } // The driver manager determines if the app is a Unicode app based on whether we call SQLDriverConnectA or // SQLDriverConnectW. Some drivers, notably Microsoft Access/Jet, change their behavior based on this, so we try // the Unicode version first. (The Access driver only supports Unicode text, but SQLDescribeCol returns SQL_CHAR // instead of SQL_WCHAR if we connect with the ANSI version. Obviously this causes lots of errors since we believe // what it tells us (SQL_CHAR).) // Python supports only UCS-2 and UCS-4, so we shouldn't need to worry about receiving surrogate pairs. However, // Windows does use UCS-16, so it is possible something would be misinterpreted as one. We may need to examine // this more. SQLRETURN ret; if (timeout > 0) { //Py_BEGIN_ALLOW_THREADS ret = SQLSetConnectAttr(hdbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)timeout, SQL_IS_UINTEGER); //Py_END_ALLOW_THREADS if (!SQL_SUCCEEDED(ret)) RaiseErrorFromHandle("SQLSetConnectAttr(SQL_ATTR_LOGIN_TIMEOUT)", hdbc, SQL_NULL_HANDLE); } if (!fAnsi) { SQLWChar connectString(pConnectString); //Py_BEGIN_ALLOW_THREADS ret = SQLDriverConnectW(hdbc, 0, connectString.get(), (SQLSMALLINT)connectString.size(), 0, 0, 0, SQL_DRIVER_NOPROMPT); //Py_END_ALLOW_THREADS if (SQL_SUCCEEDED(ret)) return true; RaiseErrorFromHandle("SQLDriverConnect", hdbc, SQL_NULL_HANDLE); return false; // The Unicode function failed. If the error is that the driver doesn't have a Unicode version (IM001), continue // to the ANSI version. // // I've commented this out since a number of common drivers are returning different errors. The MySQL 5 // driver, for example, returns IM002 "Data source name not found...". // // PyObject* error = GetErrorFromHandle("SQLDriverConnectW", hdbc, SQL_NULL_HANDLE); // if (!HasSqlState(error, "IM001")) // { // RaiseErrorFromException(error); // return false; // } // Py_XDECREF(error); } PyErr_SetString(PyExc_TypeError, "Non-unicode connection strings not supported."); return false; }
CSqlRecordsetPtr CDb2Connection::_Execute(const char *string) { SQLRETURN ret; CDb2Recordset *rs = new CDb2Recordset(); CServerIo::trace(3,"%s",string); HSTMT hStmt; if(!SQL_SUCCEEDED(m_lasterror=SQLAllocHandle(SQL_HANDLE_STMT,m_hDbc,&hStmt))) { SQLFreeStmt(hStmt,SQL_DROP); return rs; } for(std::map<int,CSqlVariant>::iterator i = m_bindVars.begin(); i!=m_bindVars.end(); ++i) { switch(i->second.type()) { case CSqlVariant::vtNull: m_sqli[i->first]=SQL_NULL_DATA; ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,NULL,0,&m_sqli[i->first]); break; case CSqlVariant::vtChar: m_sqli[i->first]=0; m_sqlv[i->first].c=i->second; ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,1,0,&m_sqlv[i->first].c,1,&m_sqli[i->first]); break; case CSqlVariant::vtUChar: m_sqli[i->first]=0; m_sqlv[i->first].c=i->second; ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,1,0,&m_sqlv[i->first].c,1,&m_sqli[i->first]); break; case CSqlVariant::vtShort: m_sqli[i->first]=0; m_sqlv[i->first].s=i->second; ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_SSHORT,SQL_INTEGER,0,0,&m_sqlv[i->first].s,0,&m_sqli[i->first]); break; case CSqlVariant::vtUShort: m_sqli[i->first]=0; m_sqlv[i->first].s=i->second; ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_USHORT,SQL_INTEGER,0,0,&m_sqlv[i->first].s,0,&m_sqli[i->first]); break; case CSqlVariant::vtInt: case CSqlVariant::vtLong: m_sqli[i->first]=0; m_sqlv[i->first].l=i->second; ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&m_sqlv[i->first].l,0,&m_sqli[i->first]); break; case CSqlVariant::vtUInt: case CSqlVariant::vtULong: m_sqli[i->first]=0; m_sqlv[i->first].l=i->second; ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&m_sqlv[i->first].l,0,&m_sqli[i->first]); break; case CSqlVariant::vtLongLong: m_sqli[i->first]=0; m_sqlv[i->first].ll=i->second; ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_SBIGINT,SQL_BIGINT,0,0,&m_sqlv[i->first].ll,0,&m_sqli[i->first]); break; case CSqlVariant::vtULongLong: m_sqli[i->first]=0; m_sqlv[i->first].ll=i->second; ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_UBIGINT,SQL_BIGINT,0,0,&m_sqlv[i->first].ll,0,&m_sqli[i->first]); break; case CSqlVariant::vtString: m_sqli[i->first]=SQL_NTS; m_sqlv[i->first].ws=cvs::wide(i->second); ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_WCHAR,SQL_WVARCHAR,(SQLINTEGER)m_sqlv[i->first].ws.size()+1,0,(SQLPOINTER)m_sqlv[i->first].ws.c_str(),(SQLINTEGER)m_sqlv[i->first].ws.size()+1,&m_sqli[i->first]); break; case CSqlVariant::vtWString: m_sqli[i->first]=SQL_NTS; m_sqlv[i->first].ws=i->second; ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_WCHAR,SQL_WVARCHAR,(SQLINTEGER)m_sqlv[i->first].ws.size()+1,0,(SQLPOINTER)m_sqlv[i->first].ws.c_str(),(SQLINTEGER)m_sqlv[i->first].ws.size()+1,&m_sqli[i->first]); break; } } rs->Init(this,hStmt,string); // Ignore return... it's handled by the error routines m_bindVars.clear(); return rs; }
/* * Show all the error information that is available */ int ODBC_Errors (char *where) { SQLTCHAR buf[512]; SQLTCHAR sqlstate[15]; SQLINTEGER native_error = 0; int force_exit = 0; SQLRETURN sts; #if (ODBCVER < 0x0300) /* * Get statement errors */ while (hstmt) { sts = SQLError (henv, hdbc, hstmt, sqlstate, &native_error, buf, NUMTCHAR (buf), NULL); if (!SQL_SUCCEEDED (sts)) break; #ifdef UNICODE fprintf (stderr, "%s = %S (%ld) SQLSTATE=%S\n", where, buf, (long) native_error, sqlstate); #else fprintf (stderr, "%s = %s (%ld) SQLSTATE=%s\n", where, buf, (long) native_error, sqlstate); #endif /* * If the driver could not be loaded, there is no point in * continuing, after reading all the error messages */ if (!TXTCMP (sqlstate, TEXT ("IM003"))) force_exit = 1; } /* * Get connection errors */ while (hdbc) { sts = SQLError (henv, hdbc, SQL_NULL_HSTMT, sqlstate, &native_error, buf, NUMTCHAR (buf), NULL); if (!SQL_SUCCEEDED (sts)) break; #ifdef UNICODE fprintf (stderr, "%s = %S (%ld) SQLSTATE=%S\n", where, buf, (long) native_error, sqlstate); #else fprintf (stderr, "%s = %s (%ld) SQLSTATE=%s\n", where, buf, (long) native_error, sqlstate); #endif /* * If the driver could not be loaded, there is no point in * continuing, after reading all the error messages */ if (!TXTCMP (sqlstate, TEXT ("IM003"))) force_exit = 1; } /* * Get environment errors */ while (henv) { sts SQLError (henv, SQL_NULL_HDBC, SQL_NULL_HSTMT, sqlstate, &native_error, buf, NUMTCHAR (buf), NULL); if (!SQL_SUCCEEDED (sts)) break; #ifdef UNICODE fprintf (stderr, "%s = %S (%ld) SQLSTATE=%S\n", where, buf, (long) native_error, sqlstate); #else fprintf (stderr, "%s = %s (%ld) SQLSTATE=%s\n", where, buf, (long) native_error, sqlstate); #endif /* * If the driver could not be loaded, there is no point in * continuing, after reading all the error messages */ if (!TXTCMP (sqlstate, TEXT ("IM003"))) force_exit = 1; } #else /* ODBCVER */ int i; /* * Get statement errors */ i = 0; while (hstmt && i < 5) { sts = SQLGetDiagRec (SQL_HANDLE_STMT, hstmt, ++i, sqlstate, &native_error, buf, NUMTCHAR (buf), NULL); if (!SQL_SUCCEEDED (sts)) break; #ifdef UNICODE fprintf (stderr, "%d: %s = %S (%ld) SQLSTATE=%S\n", i, where, buf, (long) native_error, sqlstate); #else fprintf (stderr, "%d: %s = %s (%ld) SQLSTATE=%s\n", i, where, buf, (long) native_error, sqlstate); #endif /* * If the driver could not be loaded, there is no point in * continuing, after reading all the error messages */ if (!TXTCMP (sqlstate, TEXT ("IM003"))) force_exit = 1; } /* * Get connection errors */ i = 0; while (hdbc && i < 5) { sts = SQLGetDiagRec (SQL_HANDLE_DBC, hdbc, ++i, sqlstate, &native_error, buf, NUMTCHAR (buf), NULL); if (!SQL_SUCCEEDED (sts)) break; #ifdef UNICODE fprintf (stderr, "%d: %s = %S (%ld) SQLSTATE=%S\n", i, where, buf, (long) native_error, sqlstate); #else fprintf (stderr, "%d: %s = %s (%ld) SQLSTATE=%s\n", i, where, buf, (long) native_error, sqlstate); #endif /* * If the driver could not be loaded, there is no point in * continuing, after reading all the error messages */ if (!TXTCMP (sqlstate, TEXT ("IM003"))) force_exit = 1; } /* * Get environment errors */ i = 0; while (henv && i < 5) { sts = SQLGetDiagRec (SQL_HANDLE_ENV, henv, ++i, sqlstate, &native_error, buf, NUMTCHAR (buf), NULL); if (!SQL_SUCCEEDED (sts)) break; #ifdef UNICODE fprintf (stderr, "%d: %s = %S (%ld) SQLSTATE=%S\n", i, where, buf, (long) native_error, sqlstate); #else fprintf (stderr, "%d: %s = %s (%ld) SQLSTATE=%s\n", i, where, buf, (long) native_error, sqlstate); #endif /* * If the driver could not be loaded, there is no point in * continuing, after reading all the error messages */ if (!TXTCMP (sqlstate, TEXT ("IM003"))) force_exit = 1; } #endif /* ODBCVER */ /* * Force an exit status */ if (force_exit) exit (-1); return -1; }
bool CDb2Connection::Error() const { if(SQL_SUCCEEDED(m_lasterror)) return false; return true; }
/* * Send an SQL query to the server */ static int db_unixodbc_submit_query(const db1_con_t* _h, const str* _s) { int ret = 0; SQLCHAR sqlstate[7]; if (!_h || !_s || !_s->s) { LM_ERR("invalid parameter value\n"); return -1; } /* first do some cleanup if required */ if(CON_RESULT(_h)) { SQLCloseCursor(CON_RESULT(_h)); SQLFreeHandle(SQL_HANDLE_STMT, CON_RESULT(_h)); } ret = SQLAllocHandle(SQL_HANDLE_STMT, CON_CONNECTION(_h), &CON_RESULT(_h)); if (!SQL_SUCCEEDED(ret)) { LM_ERR("statement allocation error %d\n", (int)(long)CON_CONNECTION(_h)); db_unixodbc_extract_error("SQLAllocStmt", CON_CONNECTION(_h), SQL_HANDLE_DBC, (char*)sqlstate); /* Connection broken */ if( !strncmp((char*)sqlstate,"08003",5) || !strncmp((char*)sqlstate,"08S01",5) ) { ret = reconnect(_h); if( !SQL_SUCCEEDED(ret) ) return ret; } else { return ret; } } ret=SQLExecDirect(CON_RESULT(_h), (SQLCHAR*)_s->s, _s->len); /* Handle SQL_NO_DATA as a valid return code. DELETE and UPDATE statements may return this return code if nothing was deleted/updated. */ if (!SQL_SUCCEEDED(ret) && (ret != SQL_NO_DATA)) { SQLCHAR sqlstate[7]; LM_ERR("rv=%d. Query= %.*s\n", ret, _s->len, _s->s); db_unixodbc_extract_error("SQLExecDirect", CON_RESULT(_h), SQL_HANDLE_STMT, (char*)sqlstate); /* Connection broken */ if( !strncmp((char*)sqlstate,"08003",5) || !strncmp((char*)sqlstate,"08S01",5) || !strncmp((char*)sqlstate,"HY000",5) /* ODBC 3 General error */ ) { ret = reconnect(_h); if( SQL_SUCCEEDED(ret) ) { /* Try again */ ret=SQLExecDirect(CON_RESULT(_h), (SQLCHAR*)_s->s, _s->len); if (!SQL_SUCCEEDED(ret)) { LM_ERR("rv=%d. Query= %.*s\n", ret, _s->len, _s->s); db_unixodbc_extract_error("SQLExecDirect", CON_RESULT(_h), SQL_HANDLE_STMT, (char*)sqlstate); /* Close the cursor */ SQLCloseCursor(CON_RESULT(_h)); SQLFreeHandle(SQL_HANDLE_STMT, CON_RESULT(_h)); } } } else { /* Close the cursor */ SQLCloseCursor(CON_RESULT(_h)); SQLFreeHandle(SQL_HANDLE_STMT, CON_RESULT(_h)); } } /* Store the ODBC query result */ CON_QUERY_RESULT(_h) = ret; return ret; }
bool CMssqlRecordset::Init(CMssqlConnection *parent, HSTMT hStmt, const char *command) { m_bEof = false; m_parent = parent; m_hStmt = hStmt; m_parent->m_lasterror=SQLExecDirect(m_hStmt,(SQLWCHAR*)(const wchar_t *)cvs::wide(command),SQL_NTS); CServerIo::trace(1,"MSSQL Execute Done"); if((!SQL_SUCCEEDED(m_parent->m_lasterror))&&(m_parent->m_lasterror!=SQL_NEED_DATA)) { GetStmtError(); return false; } if(m_parent->m_lasterror==SQL_NEED_DATA) { SQLPOINTER pParmID; SQLRETURN retcode=SQL_SUCCESS, putret; char *dataptr, *dataput; SQLINTEGER dataoff, datasiz; SQLINTEGER chunk=1024; CServerIo::trace(1,"MSSQL Execute requires more data"); retcode = SQLParamData(m_hStmt, &pParmID); if (retcode == SQL_NEED_DATA) { for(std::map<int,CSqlVariant>::iterator i = parent->m_bindVars.begin(); i!=parent->m_bindVars.end(); ++i) { switch(i->second.type()) { case CSqlVariant::vtString: if (parent->m_sqlv[i->first].ws.length()+1<256) CServerIo::trace(1,"MSSQL Execute this parameter is too small to be a BLOB"); else { //dataput = (char *)((const char *)parent->m_sqlv[i->first].cs.c_str()); //dataoff=0; datasiz = (SQLINTEGER)(parent->m_sqlv[i->first].cs.size()+1); dataput = (char *)((const char *)parent->m_sqlv[i->first].ws.c_str()); dataoff=0; datasiz = (SQLINTEGER)(parent->m_sqlv[i->first].ws.size()+1); //CServerIo::trace(1,"MSSQL Needs data - so put the data %d, size %d",(int)i->first,(int)parent->m_sqlv[i->first].cs.size()+1); CServerIo::trace(1,"MSSQL Needs data - so put the data %d, size %d",(int)i->first,(int)parent->m_sqlv[i->first].ws.size()+1); for (dataptr=dataput; dataoff<datasiz; dataoff+=chunk) { CServerIo::trace(1,"MSSQL put data %d offset %d bytes N\"%0.25s...%0.25s\"",dataoff, (dataoff+chunk>datasiz)?datasiz-dataoff:chunk, (const char *)cvs::narrow((const wchar_t *)(dataptr+dataoff)), ((const char *)cvs::narrow((const wchar_t *)(dataptr+dataoff))+(((dataoff+chunk>datasiz)?datasiz-dataoff:chunk)+1-25))); putret=SQLPutData(m_hStmt, (SQLPOINTER)(dataptr+(sizeof(wchar_t)*dataoff)), (dataoff+chunk>datasiz)?(sizeof(wchar_t)*(datasiz-dataoff)):(sizeof(wchar_t)*chunk)); if(!SQL_SUCCEEDED(putret)) { m_parent->m_lasterror = putret; GetStmtError(); return false; } /*switch (putret) { case SQL_SUCCESS: CServerIo::trace(1,"SQL Put Data returned SQL_SUCCESS"); break; case SQL_SUCCESS_WITH_INFO: CServerIo::trace(1,"SQL Put Data returned SQL_SUCCESS_WITH_INFO"); break; case SQL_STILL_EXECUTING: CServerIo::trace(1,"SQL Put Data returned SQL_STILL_EXECUTING"); break; case SQL_ERROR: CServerIo::trace(1,"SQL Put Data returned SQL_ERROR"); break; case SQL_INVALID_HANDLE: CServerIo::trace(1,"SQL Put Data returned SQL_INVALID_HANDLE"); break; default: CServerIo::trace(1,"SQL Put Data returned some other error."); }*/ } CServerIo::trace(1,"MSSQL call ParamData again"); retcode = SQLParamData(m_hStmt, &pParmID); if (retcode==SQL_SUCCESS) CServerIo::trace(1,"MSSQL call ParamData returned OK - no more data"); else if (retcode==SQL_NEED_DATA) CServerIo::trace(1,"MSSQL call ParamData returned need more data"); } break; default: break; } } } else { retcode=SQL_SUCCESS; } if (retcode==SQL_SUCCESS) CServerIo::trace(1,"MSSQL call ParamData returned OK - no more data"); else if (retcode==SQL_NEED_DATA) CServerIo::trace(1,"MSSQL call ParamData returned need more data"); else if(!SQL_SUCCEEDED(retcode)) { CServerIo::trace(1,"MSSQL call ParamData returned some sort of failure so returning..."); m_parent->m_lasterror = retcode; GetStmtError(); return false; } } CServerIo::trace(1,"MSSQL Execute all complete now get the Number of Result Columns"); if(!SQL_SUCCEEDED(m_parent->m_lasterror = SQLNumResultCols(m_hStmt,&m_num_fields))) { GetStmtError(); return false; } m_sqlfields.resize(m_num_fields); for(SQLSMALLINT n=0; n<m_num_fields; n++) { SQLRETURN rc; SQLWCHAR szCol[128]; SQLSMALLINT len = sizeof(szCol); rc = m_parent->m_lasterror = SQLDescribeCol(hStmt,n+1,szCol,sizeof(szCol),&len,&m_sqlfields[n].type,&m_sqlfields[n].size,&m_sqlfields[n].decimal,&m_sqlfields[n].null); if(!SQL_SUCCEEDED(rc)) { GetStmtError(); return false; } szCol[len]='\0'; m_sqlfields[n].field = n; m_sqlfields[n].hStmt = m_hStmt; m_sqlfields[n].name = szCol; SQLINTEGER fldlen = 0; SQLSMALLINT ctype; switch(m_sqlfields[n].type) { case SQL_UNKNOWN_TYPE: CServerIo::trace(1,"Unable to bind column %s as it is SQL_UNKNOWN_TYPE",(const char *)szCol); break; // Don't bind case SQL_CHAR: case SQL_VARCHAR: ctype = SQL_C_WCHAR; fldlen = m_sqlfields[n].size; break; case SQL_DECIMAL: ctype = SQL_C_WCHAR; fldlen = m_sqlfields[n].size + m_sqlfields[n].decimal + 1; break; case SQL_NUMERIC: case SQL_INTEGER: case SQL_SMALLINT: ctype = SQL_C_LONG; fldlen = sizeof(long); break; case SQL_FLOAT: case SQL_REAL: case SQL_DOUBLE: ctype = SQL_C_DOUBLE; fldlen = sizeof(double); break; case SQL_DATETIME: ctype = SQL_C_WCHAR; fldlen = 64; break; } m_sqlfields[n].ctype = ctype; m_sqlfields[n].fldlen = fldlen; if(m_sqlfields[n].fldlen) { m_sqlfields[n].data = malloc(m_sqlfields[n].fldlen); if(!SQL_SUCCEEDED(m_parent->m_lasterror = SQLBindCol(m_hStmt,n+1,m_sqlfields[n].ctype,m_sqlfields[n].data,m_sqlfields[n].fldlen,&m_sqlfields[n].datalen))) { GetStmtError(); CServerIo::trace(1,"Unable to bind column %s due to error",(const char*)szCol); return false; } } } if(m_num_fields) { if(!Next() && !m_bEof) return false; } return true; }
SQLRETURN SQL_API SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind) { ODBCStmt *stmt = (ODBCStmt *) StatementHandle; ODBCDesc *desc; /* Application Row Descriptor */ #ifdef ODBCDEBUG ODBCLOG("SQLBindCol " PTRFMT " %u %s " LENFMT "\n", PTRFMTCAST StatementHandle, (unsigned int) ColumnNumber, translateCType(TargetType), LENCAST BufferLength); #endif if (!isValidStmt(stmt)) return SQL_INVALID_HANDLE; assert(stmt->Dbc); clearStmtErrors(stmt); /* check input parameters */ /* column number 0 (Bookmark column) is not supported */ if (ColumnNumber == 0) { if (TargetType == SQL_C_BOOKMARK || TargetType == SQL_C_VARBOOKMARK) { /* Optional feature not implemented */ addStmtError(stmt, "HYC00", NULL, 0); } else { /* Restricted data type attribute violation */ addStmtError(stmt, "07006", NULL, 0); } return SQL_ERROR; } if (stmt->State >= EXECUTED1 && ColumnNumber > stmt->ImplRowDescr->sql_desc_count) { /* Invalid descriptor index */ addStmtError(stmt, "07009", NULL, 0); return SQL_ERROR; } /* For safety: limit the maximum number of columns to bind */ if (ColumnNumber > MONETDB_MAX_BIND_COLS) { /* General error */ addStmtError(stmt, "HY000", "Maximum number of bind columns (8192) exceeded", 0); return SQL_ERROR; } /* can't let SQLSetDescField below do this check since it returns the wrong error code if the type is incorrect */ switch (TargetType) { case SQL_C_CHAR: case SQL_C_WCHAR: case SQL_C_BINARY: case SQL_C_BIT: case SQL_C_STINYINT: case SQL_C_UTINYINT: case SQL_C_TINYINT: case SQL_C_SSHORT: case SQL_C_USHORT: case SQL_C_SHORT: case SQL_C_SLONG: case SQL_C_ULONG: case SQL_C_LONG: case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_NUMERIC: case SQL_C_FLOAT: case SQL_C_DOUBLE: case SQL_C_TYPE_DATE: case SQL_C_TYPE_TIME: case SQL_C_TYPE_TIMESTAMP: case SQL_C_INTERVAL_YEAR: case SQL_C_INTERVAL_MONTH: case SQL_C_INTERVAL_YEAR_TO_MONTH: case SQL_C_INTERVAL_DAY: case SQL_C_INTERVAL_HOUR: case SQL_C_INTERVAL_MINUTE: case SQL_C_INTERVAL_SECOND: case SQL_C_INTERVAL_DAY_TO_HOUR: case SQL_C_INTERVAL_DAY_TO_MINUTE: case SQL_C_INTERVAL_DAY_TO_SECOND: case SQL_C_INTERVAL_HOUR_TO_MINUTE: case SQL_C_INTERVAL_HOUR_TO_SECOND: case SQL_C_INTERVAL_MINUTE_TO_SECOND: case SQL_C_GUID: case SQL_C_DEFAULT: break; default: /* Invalid application buffer type */ addStmtError(stmt, "HY003", NULL, 0); return SQL_ERROR; } if (BufferLength < 0) { /* Invalid string or buffer length */ addStmtError(stmt, "HY090", NULL, 0); return SQL_ERROR; } desc = stmt->ApplRowDescr; if (TargetValuePtr == NULL && ColumnNumber == desc->sql_desc_count) { int i = desc->sql_desc_count - 1; while (i > 0 && desc->descRec[i].sql_desc_data_ptr == NULL) i--; setODBCDescRecCount(desc, i); } else { ODBCDescRec *rec; SQLRETURN rc; if (ColumnNumber > desc->sql_desc_count) setODBCDescRecCount(desc, ColumnNumber); rc = SQLSetDescField_(desc, ColumnNumber, SQL_DESC_CONCISE_TYPE, (SQLPOINTER) (ssize_t) TargetType, 0); if (!SQL_SUCCEEDED(rc)) return rc; rec = &desc->descRec[ColumnNumber]; rec->sql_desc_octet_length = BufferLength; rec->sql_desc_data_ptr = TargetValuePtr; rec->sql_desc_indicator_ptr = StrLen_or_Ind; rec->sql_desc_octet_length_ptr = StrLen_or_Ind; } return SQL_SUCCESS; }
bool CQuery::BindParameter( _In_ SQLUSMALLINT parameterNumber, _In_ SQLSMALLINT inputOutputType, _In_ SQLSMALLINT valueType, _In_ SQLSMALLINT parameterType, _In_ SQLUINTEGER columnSize, _In_ SQLSMALLINT decimalDigits, _In_ SQLPOINTER parameterValuePtr, _In_ SQLINTEGER bufferLength, _In_ SQLINTEGER *strLen_or_IndPtr ) { return SQL_SUCCEEDED( SQLBindParameter( m_hStmt, parameterNumber, inputOutputType, valueType, parameterType, columnSize, decimalDigits, parameterValuePtr, bufferLength, strLen_or_IndPtr ) ); }
SQLRETURN SQLExecDirectW( SQLHSTMT statement_handle, SQLWCHAR *statement_text, SQLINTEGER text_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR *s1; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLEXECDIRECTW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLEXECDIRECTW( parent_statement -> connection, statement, statement_text, text_length ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { /* * allocate some space for the buffer */ if ( statement_text && text_length == SQL_NTS ) { s1 = malloc( wide_strlen( statement_text ) * 2 + LOG_MESSAGE_LEN * 2 ); } else if ( statement_text ) { s1 = malloc( text_length + LOG_MESSAGE_LEN * 2 ); } else { s1 = malloc( LOG_MESSAGE_LEN * 2 ); } sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tSQL = %s", statement, __wstring_with_length( s1, statement_text, text_length )); free( s1 ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( !statement_text ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( text_length <= 0 && text_length != SQL_NTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLEXECDIRECT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver || CHECK_SQLEXECDIRECTW( statement -> connection )) { #ifdef NR_PROBE if ( !CHECK_SQLEXECDIRECTW( statement -> connection ) || !CHECK_SQLNUMRESULTCOLS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #else if ( !CHECK_SQLEXECDIRECTW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #endif ret = SQLEXECDIRECTW( statement -> connection, statement -> driver_stmt, statement_text, text_length ); } else { SQLCHAR *as1 = NULL; int clen; #ifdef NR_PROBE if ( !CHECK_SQLEXECDIRECT( statement -> connection ) || !CHECK_SQLNUMRESULTCOLS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #else if ( !CHECK_SQLEXECDIRECT( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #endif as1 = (SQLCHAR*) unicode_to_ansi_alloc( statement_text, text_length, statement -> connection, &clen ); text_length = clen; ret = SQLEXECDIRECT( statement -> connection, statement -> driver_stmt, as1, text_length ); if ( as1 ) free( as1 ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE SQLRETURN local_ret; /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE ); } local_ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); if ( statement -> numcols > 0 ) { statement -> state = STATE_S5; } else { statement -> state = STATE_S4; } #else /* * We don't know for sure */ statement -> hascols = 1; statement -> state = STATE_S5; #endif statement -> prepared = 0; /* * there is a issue here with transactions, but for the * moment * statement -> connection -> state = STATE_C6; */ } else if ( ret == SQL_NEED_DATA ) { statement -> interupted_func = SQL_API_SQLEXECDIRECT; statement -> interupted_state = statement -> state; statement -> state = STATE_S8; statement -> prepared = 0; } else if ( ret == SQL_PARAM_DATA_AVAILABLE ) { statement -> interupted_func = SQL_API_SQLEXECDIRECT; statement -> interupted_state = statement -> state; statement -> state = STATE_S13; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLEXECDIRECT; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; statement -> prepared = 0; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s2 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret ); }
std::string get_dbms_version() { if(SQL_SUCCEEDED(m_dbms_info_available)) return std::string((char *)m_dbms_ver); return std::string(""); }
static SQLRETURN MNDBBrowseConnect(ODBCDbc *dbc, SQLCHAR *InConnectionString, SQLSMALLINT StringLength1, SQLCHAR *OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength2Ptr) { char *key, *attr; char *dsn, *uid, *pwd, *host, *dbname; int port; SQLSMALLINT len = 0; char buf[256]; int n; SQLRETURN rc; #ifdef ODBCDEBUG int allocated = 0; #endif fixODBCstring(InConnectionString, StringLength1, SQLSMALLINT, addDbcError, dbc, return SQL_ERROR); #ifdef ODBCDEBUG ODBCLOG(" \"%.*s\"\n", (int) StringLength1, (char*) InConnectionString); #endif /* check connection state, should not be connected */ if (dbc->Connected) { /* Connection name in use */ addDbcError(dbc, "08002", NULL, 0); return SQL_ERROR; } dsn = dbc->dsn ? strdup(dbc->dsn) : NULL; uid = dbc->uid ? strdup(dbc->uid) : NULL; pwd = dbc->pwd ? strdup(dbc->pwd) : NULL; host = dbc->host ? strdup(dbc->host) : NULL; port = dbc->port; dbname = dbc->dbname ? strdup(dbc->dbname) : NULL; while ((n = ODBCGetKeyAttr(&InConnectionString, &StringLength1, &key, &attr)) > 0) { if (strcasecmp(key, "dsn") == 0 && dsn == NULL) { if (dsn) free(dsn); dsn = attr; } else if (strcasecmp(key, "uid") == 0 && uid == NULL) { if (uid) free(uid); uid = attr; } else if (strcasecmp(key, "pwd") == 0 && pwd == NULL) { if (pwd) free(pwd); pwd = attr; } else if (strcasecmp(key, "host") == 0 && host == NULL) { if (host) free(host); host = attr; } else if (strcasecmp(key, "port") == 0 && port == 0) { port = atoi(attr); free(attr); } else if (strcasecmp(key, "database") == 0 && dbname == NULL) { if (dbname) free(dbname); dbname = attr; #ifdef ODBCDEBUG } else if (strcasecmp(key, "logfile") == 0 && getenv("ODBCDEBUG") == NULL) { /* environment trumps everything */ if (ODBCdebug) free((void *) ODBCdebug); /* discard const */ ODBCdebug = attr; allocated = 1; #endif } else free(attr); free(key); } if (n < 0) goto nomem; if (dsn) { if (uid == NULL) { n = SQLGetPrivateProfileString(dsn, "uid", "", buf, sizeof(buf), "odbc.ini"); if (n > 0 && buf[0]) { uid = strdup(buf); if (uid == NULL) goto nomem; } } if (pwd == NULL) { n = SQLGetPrivateProfileString(dsn, "pwd", "", buf, sizeof(buf), "odbc.ini"); if (n > 0 && buf[0]) { pwd = strdup(buf); if (pwd == NULL) goto nomem; } } if (host == NULL) { n = SQLGetPrivateProfileString(dsn, "host", "", buf, sizeof(buf), "odbc.ini"); if (n > 0 && buf[0]) { host = strdup(buf); if (host == NULL) goto nomem; } } if (port == 0) { n = SQLGetPrivateProfileString(dsn, "port", "", buf, sizeof(buf), "odbc.ini"); if (n > 0 && buf[0]) { port = atoi(buf); } } if (dbname == NULL) { n = SQLGetPrivateProfileString(dsn, "database", "", buf, sizeof(buf), "odbc.ini"); if (n > 0 && buf[0]) { dbname = strdup(buf); if (dbname == NULL) goto nomem; } } #ifdef ODBCDEBUG if (!allocated && getenv("ODBCDEBUG") == NULL) { /* if not set from InConnectionString argument * or environment, look in profile */ n = SQLGetPrivateProfileString(dsn, "logfile", "", buf, sizeof(buf), "odbc.ini"); if (n > 0 && buf[0]) ODBCdebug = strdup(buf); } #endif } if (uid != NULL && pwd != NULL) { rc = MNDBConnect(dbc, (SQLCHAR *) dsn, SQL_NTS, (SQLCHAR *) uid, SQL_NTS, (SQLCHAR *) pwd, SQL_NTS, host, port, dbname); if (SQL_SUCCEEDED(rc)) { rc = ODBCConnectionString(rc, dbc, OutConnectionString, BufferLength, StringLength2Ptr, dsn, uid, pwd, host, port, dbname); } } else { if (uid == NULL) { if (BufferLength > 0) strncpy((char *) OutConnectionString, "UID:Login ID=?;", BufferLength); len += 15; OutConnectionString += 15; BufferLength -= 15; } if (pwd == NULL) { if (BufferLength > 0) strncpy((char *) OutConnectionString, "PWD:Password=?;", BufferLength); len += 15; OutConnectionString += 15; BufferLength -= 15; } if (host == NULL) { if (BufferLength > 0) strncpy((char *) OutConnectionString, "*HOST:Server=?;", BufferLength); len += 15; OutConnectionString += 15; BufferLength -= 15; } if (port == 0) { if (BufferLength > 0) strncpy((char *) OutConnectionString, "*PORT:Port=?;", BufferLength); len += 13; OutConnectionString += 13; BufferLength -= 13; } if (dbname == NULL) { if (BufferLength > 0) strncpy((char *) OutConnectionString, "*DATABASE:Database=?;", BufferLength); len += 21; OutConnectionString += 21; BufferLength -= 21; } #ifdef ODBCDEBUG if (ODBCdebug == NULL) { if (BufferLength > 0) strncpy((char *) OutConnectionString, "*LOGFILE:Debug log file=?;", BufferLength); len += 26; OutConnectionString += 26; BufferLength -= 26; } #endif if (StringLength2Ptr) *StringLength2Ptr = len; rc = SQL_NEED_DATA; } bailout: if (dsn) free(dsn); if (uid) free(uid); if (pwd) free(pwd); if (host) free(host); if (dbname) free(dbname); return rc; nomem: /* Memory allocation error */ addDbcError(dbc, "HY001", NULL, 0); rc = SQL_ERROR; goto bailout; }
static PyObject* CnxnInfo_New(Connection* cnxn) { #ifdef _MSC_VER #pragma warning(disable : 4365) #endif CnxnInfo* p = PyObject_NEW(CnxnInfo, &CnxnInfoType); if (!p) return 0; Object info((PyObject*)p); // set defaults p->odbc_major = 3; p->odbc_minor = 50; p->supports_describeparam = false; p->datetime_precision = 19; // default: "yyyy-mm-dd hh:mm:ss" p->need_long_data_len = false; // WARNING: The GIL lock is released for the *entire* function here. Do not touch any objects, call Python APIs, // etc. We are simply making ODBC calls and setting atomic values (ints & chars). Also, make sure the lock gets // released -- do not add an early exit. SQLRETURN ret; Py_BEGIN_ALLOW_THREADS char szVer[20]; SQLSMALLINT cch = 0; ret = SQLGetInfo(cnxn->hdbc, SQL_DRIVER_ODBC_VER, szVer, _countof(szVer), &cch); if (SQL_SUCCEEDED(ret)) { char* dot = strchr(szVer, '.'); if (dot) { *dot = '\0'; p->odbc_major=(char)atoi(szVer); p->odbc_minor=(char)atoi(dot + 1); } } char szYN[2]; if (SQL_SUCCEEDED(SQLGetInfo(cnxn->hdbc, SQL_DESCRIBE_PARAMETER, szYN, _countof(szYN), &cch))) p->supports_describeparam = szYN[0] == 'Y'; if (SQL_SUCCEEDED(SQLGetInfo(cnxn->hdbc, SQL_NEED_LONG_DATA_LEN, szYN, _countof(szYN), &cch))) p->need_long_data_len = (szYN[0] == 'Y'); // These defaults are tiny, but are necessary for Access. p->varchar_maxlength = 255; p->wvarchar_maxlength = 255; p->binary_maxlength = 510; HSTMT hstmt = 0; if (SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, cnxn->hdbc, &hstmt))) { SQLINTEGER columnsize; if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_TYPE_TIMESTAMP)) && SQL_SUCCEEDED(SQLFetch(hstmt))) if (SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, sizeof(columnsize), 0))) p->datetime_precision = (int)columnsize; if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_VARCHAR)) && SQL_SUCCEEDED(SQLFetch(hstmt))) if (SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, sizeof(columnsize), 0))) p->varchar_maxlength = (int)columnsize; if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_WVARCHAR)) && SQL_SUCCEEDED(SQLFetch(hstmt))) if (SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, sizeof(columnsize), 0))) p->wvarchar_maxlength = (int)columnsize; if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_BINARY)) && SQL_SUCCEEDED(SQLFetch(hstmt))) if (SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, sizeof(columnsize), 0))) p->binary_maxlength = (int)columnsize; SQLFreeStmt(hstmt, SQL_CLOSE); } Py_END_ALLOW_THREADS // WARNING: Released the lock now. return info.Detach(); }
int main(int argc, char *argv[]) { SQLINTEGER cbInString = SQL_NTS; char buf[256]; SQLRETURN ret; unsigned char sqlstate[6]; Connect(); Command(Statement, "CREATE TABLE #urls ( recdate DATETIME ) "); /* test implicit conversion error */ if (CommandWithResult(Statement, "INSERT INTO #urls ( recdate ) VALUES ( '2003-10-1 10:11:1 0' )") != SQL_ERROR) { fprintf(stderr, "SQLExecDirect success instead of failing!\n"); return 1; } /* test prepared implicit conversion error */ if (!SQL_SUCCEEDED(SQLPrepare(Statement, (SQLCHAR *) "INSERT INTO #urls ( recdate ) VALUES ( ? )", SQL_NTS))) { fprintf(stderr, "SQLPrepare failure!\n"); return 1; } strcpy(buf, "2003-10-1 10:11:1 0"); if (!SQL_SUCCEEDED (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 128, 0, buf, sizeof(buf), &cbInString))) { fprintf(stderr, "SQLBindParameter failure!\n"); return 1; } if (SQLExecute(Statement) != SQL_ERROR) { fprintf(stderr, "SQLExecute succeeded instead of failing! (line %d)\n", __LINE__); return 1; } ret = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, buf, sizeof(buf), NULL); if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) { fprintf(stderr, "Error not set (line %d)\n", __LINE__); return 1; } printf("err=%s\n", buf); /* try to prepare and execute a statement with error (from DBD::ODBC test) */ SQLPrepare(Statement, (SQLCHAR *) "SELECT XXNOTCOLUMN FROM sysobjects", SQL_NTS); if (SQLExecute(Statement) != SQL_ERROR) { fprintf(stderr, "SQLExecute succeeded instead of failing! (line %d)\n", __LINE__); return 1; } ret = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, buf, sizeof(buf), NULL); if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) { fprintf(stderr, "Error not set (line %d) ret=%d\n", __LINE__, (int)ret); return 1; } printf("err=%s\n", buf); Disconnect(); printf("Done.\n"); return 0; }
static SQLRETURN extract_sql_error_field( EHEAD *head, SQLSMALLINT rec_number, SQLSMALLINT diag_identifier, SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length, SQLSMALLINT *string_length_ptr ) { ERROR *ptr; /* * check the header fields first */ switch( diag_identifier ) { case SQL_DIAG_CURSOR_ROW_COUNT: case SQL_DIAG_ROW_COUNT: { SQLLEN val; SQLRETURN ret; if ( head -> handle_type != SQL_HANDLE_STMT ) { return SQL_ERROR; } else if ( head -> header_set ) { switch( diag_identifier ) { case SQL_DIAG_CURSOR_ROW_COUNT: if ( SQL_SUCCEEDED( head -> diag_cursor_row_count_ret ) && diag_info_ptr ) { *((SQLLEN*)diag_info_ptr) = head -> diag_cursor_row_count; } return head -> diag_cursor_row_count_ret; case SQL_DIAG_ROW_COUNT: if ( SQL_SUCCEEDED( head -> diag_row_count_ret ) && diag_info_ptr ) { *((SQLLEN*)diag_info_ptr) = head -> diag_row_count; } return head -> diag_row_count_ret; } } else if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { ret = SQLGETDIAGFIELDW( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { ret = SQLGETDIAGFIELD( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else if ( CHECK_SQLROWCOUNT( __get_connection( head ))) { ret = DEF_SQLROWCOUNT( __get_connection( head ), __get_driver_handle( head ), &val ); if ( !SQL_SUCCEEDED( ret )) { return ret; } } else { val = 0; } if ( diag_info_ptr ) { memcpy( diag_info_ptr, &val, sizeof( val )); } } return SQL_SUCCESS; case SQL_DIAG_DYNAMIC_FUNCTION: { SQLRETURN ret; if ( head -> handle_type != SQL_HANDLE_STMT ) { return SQL_ERROR; } else if ( head -> header_set ) { if ( SQL_SUCCEEDED( head -> diag_dynamic_function_ret ) && diag_info_ptr ) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, head -> diag_dynamic_function, buffer_length, __get_connection( head )); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( head -> diag_dynamic_function ); } } return head -> diag_dynamic_function_ret; } else if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { SQLWCHAR *s1; if ( buffer_length > 0 ) { s1 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 )); } ret = SQLGETDIAGFIELDW( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, s1 ? s1 : diag_info_ptr, buffer_length, string_length_ptr ); if ( SQL_SUCCEEDED( ret ) && diag_info_ptr && s1 ) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, s1, buffer_length, __get_connection( head )); } if ( s1 ) { free( s1 ); } return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { ret = SQLGETDIAGFIELD( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } if ( diag_info_ptr ) { strcpy( diag_info_ptr, "" ); } } return SQL_SUCCESS; case SQL_DIAG_DYNAMIC_FUNCTION_CODE: { SQLINTEGER val; SQLRETURN ret; if ( head -> handle_type != SQL_HANDLE_STMT ) { return SQL_ERROR; } else if ( head -> header_set ) { if ( SQL_SUCCEEDED( head -> diag_dynamic_function_code_ret ) && diag_info_ptr ) { *((SQLINTEGER*)diag_info_ptr) = head -> diag_dynamic_function_code; } return head -> diag_dynamic_function_code_ret; } else if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { ret = SQLGETDIAGFIELDW( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { ret = SQLGETDIAGFIELD( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else { val = SQL_DIAG_UNKNOWN_STATEMENT; } if ( diag_info_ptr ) { memcpy( diag_info_ptr, &val, sizeof( val )); } } return SQL_SUCCESS; case SQL_DIAG_NUMBER: { SQLINTEGER val; val = head -> sql_diag_head.internal_count + head -> sql_diag_head.error_count; if ( diag_info_ptr ) { memcpy( diag_info_ptr, &val, sizeof( val )); } } return SQL_SUCCESS; case SQL_DIAG_RETURNCODE: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &head -> return_code, sizeof( head -> return_code )); } } return SQL_SUCCESS; } /* * else check the records */ if ( rec_number < 1 ) { return SQL_ERROR; } if ( rec_number <= head -> sql_diag_head.internal_count ) { /* * local errors */ ptr = head -> sql_diag_head.internal_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } } else if ( !__is_env( head ) && __get_connection( head ) -> state != STATE_C2 ) { rec_number -= head -> sql_diag_head.internal_count; if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { SQLRETURN ret; SQLWCHAR *s1 = NULL; int char_buffer_len = sizeof( SQLWCHAR ) * buffer_length; if ( buffer_length > 0 ) { s1 = malloc( char_buffer_len + sizeof( SQLWCHAR )); } ret = SQLGETDIAGFIELDW( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, diag_identifier, s1 ? s1 : diag_info_ptr, char_buffer_len, string_length_ptr ); if ( SQL_SUCCEEDED( ret ) && s1 && diag_info_ptr ) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, s1, SQL_NTS, __get_connection( head )); } if ( s1 ) { free( s1 ); } if ( string_length_ptr && *string_length_ptr > 0 ) { *string_length_ptr /= sizeof( SQLWCHAR ); } if ( SQL_SUCCEEDED( ret ) && diag_identifier == SQL_DIAG_SQLSTATE ) { /* * map 3 to 2 if required */ if ( diag_info_ptr ) { if ( diag_info_ptr ) __map_error_state( diag_info_ptr, __get_version( head )); } } return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { SQLRETURN ret; ret = SQLGETDIAGFIELD( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); if ( SQL_SUCCEEDED( ret ) && diag_identifier == SQL_DIAG_SQLSTATE ) { /* * map 3 to 2 if required */ if ( diag_info_ptr ) { if ( diag_info_ptr ) __map_error_state( diag_info_ptr, __get_version( head )); } } return ret; } else { ptr = head -> sql_diag_head.error_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } } } else { return SQL_NO_DATA; } /* * if we are here ptr should point to the local error * record */ switch( diag_identifier ) { case SQL_DIAG_CLASS_ORIGIN: { if ( SQL_SUCCEEDED( ptr -> diag_class_origin_ret )) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_class_origin, buffer_length, __get_connection( head )); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_class_origin ); } return ptr -> diag_class_origin_ret; } else { return ptr -> diag_class_origin_ret; } } break; case SQL_DIAG_COLUMN_NUMBER: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &ptr -> diag_column_number, sizeof( SQLINTEGER )); } return SQL_SUCCESS; } break; case SQL_DIAG_CONNECTION_NAME: { if ( SQL_SUCCEEDED( ptr -> diag_connection_name_ret )) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_connection_name, buffer_length, __get_connection( head )); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_connection_name ); } return ptr -> diag_connection_name_ret; } else { return ptr -> diag_connection_name_ret; } } break; case SQL_DIAG_MESSAGE_TEXT: { char *str; int ret = SQL_SUCCESS; str = unicode_to_ansi_alloc( ptr -> msg, SQL_NTS, __get_connection( head )); if ( diag_info_ptr ) { if ( buffer_length >= strlen( str ) + 1 ) { strcpy( diag_info_ptr, str ); } else { ret = SQL_SUCCESS_WITH_INFO; memcpy( diag_info_ptr, str, buffer_length - 1 ); (( char * ) diag_info_ptr )[ buffer_length - 1 ] = '\0'; } } if ( string_length_ptr ) { *string_length_ptr = strlen( str ); } if ( str ) { free( str ); } return ret; } break; case SQL_DIAG_NATIVE: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &ptr -> native_error, sizeof( SQLINTEGER )); } return SQL_SUCCESS; } break; case SQL_DIAG_ROW_NUMBER: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &ptr -> diag_row_number, sizeof( SQLLEN )); } return SQL_SUCCESS; } break; case SQL_DIAG_SERVER_NAME: { if ( SQL_SUCCEEDED( ptr -> diag_server_name_ret )) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_server_name, buffer_length, __get_connection( head )); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_server_name ); } return ptr -> diag_server_name_ret; } else { return ptr -> diag_server_name_ret; } } break; case SQL_DIAG_SQLSTATE: { char *str; int ret = SQL_SUCCESS; str = unicode_to_ansi_alloc( ptr -> sqlstate, SQL_NTS, __get_connection( head )); if ( diag_info_ptr ) { if ( buffer_length >= strlen( str ) + 1 ) { strcpy( diag_info_ptr, str ); } else { ret = SQL_SUCCESS_WITH_INFO; memcpy( diag_info_ptr, str, buffer_length - 1 ); (( char * ) diag_info_ptr )[ buffer_length - 1 ] = '\0'; } /* * map 3 to 2 if required */ if ( diag_info_ptr ) __map_error_state( diag_info_ptr, __get_version( head )); } if ( string_length_ptr ) { *string_length_ptr = strlen( str ); } if ( str ) { free( str ); } return ret; } break; case SQL_DIAG_SUBCLASS_ORIGIN: { if ( SQL_SUCCEEDED( ptr -> diag_subclass_origin_ret )) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_subclass_origin, buffer_length, __get_connection( head )); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_subclass_origin ); } return ptr -> diag_subclass_origin_ret; } else { return ptr -> diag_subclass_origin_ret; } } break; } return SQL_SUCCESS; }