SQLRETURN unixodbc_backend_debug::do_describe_parameter(SQLHSTMT statement_handle, SQLUSMALLINT parameter_number, SQLSMALLINT * data_type, SQLULEN * column_size, SQLSMALLINT * decimal_digits, SQLSMALLINT * nullable) const { std::cout << " *DEBUG* describe_parameter"; auto const return_code = SQLDescribeParam(statement_handle, parameter_number, data_type, column_size, decimal_digits, nullable); std::cout << " (return code " << return_code << ")" << std::endl; return return_code; }
ODBCParam::ODBCParam(const SQLHSTMT hdl_stmt, const int i_col) { type = 0; decimal = 0; nullable = 0; col_size = 0; if (!SQL_SUCCEEDED( SQLDescribeParam(hdl_stmt, i_col, &type, &col_size, &decimal, &nullable))) { ODBCContext::extract_error(SQL_HANDLE_STMT, hdl_stmt); raise_warning("unable to retrieve param information."); } }
SQLRETURN unixodbc_backend::do_describe_parameter(SQLHSTMT statement_handle, SQLUSMALLINT parameter_number, SQLSMALLINT * data_type, SQLULEN * column_size, SQLSMALLINT * decimal_digits, SQLSMALLINT * nullable) const { return SQLDescribeParam(statement_handle, parameter_number, data_type, column_size, decimal_digits, nullable); }
/** * Fill cols data structure with parameters info and bind * query parameters to cols data fields. * * A query has to be already prepared using SQLPrepare() * * On error ODBC handle structure resources are cleared and error messages * are added to the error list. * * @param thisHandle ODBC handle structure with already prepared query * @param data data.frame-like structure with query data (columns refer * to query parameters, rows to query executions) - used to determine * query params C types * @param vtest debug level: * 0-no debug, * 1-verbose, * 2-verbose with no query execution * @retval 1 on success, -1 on error */ SQLRETURN BindParameters(pRODBCHandle thisHandle, SEXP data){ SQLRETURN res = 0; SQLSMALLINT nparams, col; /* Check the number of Query parameters */ res = SQLNumParams(thisHandle->hStmt, &nparams); SQL_RESULT_CHECK(res, thisHandle, _("[RODBCext] Error: SQLNumParams failed"), res); if(nparams > 0 && nparams != LENGTH(data)){ SQL_RESULT_CHECK( SQL_ERROR, thisHandle, _("[RODBCext] Error: Number of parameters in query do not match number of columns in data"), res ); } cachenbind_free(thisHandle); thisHandle->ColData = Calloc(nparams, COLUMNS); thisHandle->nAllocated = nparams; for(col = 0; col < nparams; col++) { COLUMNS *column = &(thisHandle->ColData[col]); column->ColName[0] = '\0'; /* We don't know parameter name but we really don't need to */ res = SQLDescribeParam(thisHandle->hStmt, col + 1, &column->DataType, &column->ColSize, &column->DecimalDigits, &column->Nullable); /* ODBC driver does not support SQLDescribeParam - try to use default values and rely on the ODBC casting */ if(res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO){ switch(TYPEOF(VECTOR_ELT(data, col))) { case REALSXP: column->DataType = SQL_DOUBLE; column->ColSize = DOUBLE_COL_SIZE; break; case INTSXP: column->DataType = SQL_INTEGER; break; default: column->DataType = SQL_VARCHAR; column->ColSize = COLMAX; break; } } /* Bind parameter */ switch(TYPEOF(VECTOR_ELT(data, col))) { case REALSXP: res = SQLBindParameter( thisHandle->hStmt, col + 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, column->DataType, column->ColSize, column->DecimalDigits, column->RData, 0, column->IndPtr ); break; case INTSXP: res = SQLBindParameter( thisHandle->hStmt, col + 1, SQL_PARAM_INPUT, SQL_C_SLONG, column->DataType, column->ColSize, column->DecimalDigits, column->IData, 0, column->IndPtr ); break; default: if(column->pData){ Free(column->pData); } column->pData = Calloc(column->ColSize + 1, char); res = SQLBindParameter( thisHandle->hStmt, col + 1, SQL_PARAM_INPUT, SQL_C_CHAR, column->DataType, column->ColSize, column->DecimalDigits, column->pData, 0, column->IndPtr ); break; } SQL_RESULT_CHECK(res, thisHandle, _("[RODBCext] Error: SQLBindParameter failed"), res); } return 1; }
static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type) { pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data; RETCODE rc; SWORD sqltype = 0, ctype = 0, scale = 0, nullable = 0; SQLULEN precision = 0; pdo_odbc_param *P; zval *parameter; /* we're only interested in parameters for prepared SQL right now */ if (param->is_param) { switch (event_type) { case PDO_PARAM_EVT_FETCH_PRE: case PDO_PARAM_EVT_FETCH_POST: case PDO_PARAM_EVT_NORMALIZE: /* Do nothing */ break; case PDO_PARAM_EVT_FREE: P = param->driver_data; if (P) { efree(P); } break; case PDO_PARAM_EVT_ALLOC: { /* figure out what we're doing */ switch (PDO_PARAM_TYPE(param->param_type)) { case PDO_PARAM_LOB: break; case PDO_PARAM_STMT: return 0; default: break; } rc = SQLDescribeParam(S->stmt, (SQLUSMALLINT) param->paramno+1, &sqltype, &precision, &scale, &nullable); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { /* MS Access, for instance, doesn't support SQLDescribeParam, * so we need to guess */ sqltype = PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB ? SQL_LONGVARBINARY : SQL_LONGVARCHAR; precision = 4000; scale = 5; nullable = 1; if (param->max_value_len > 0) { precision = param->max_value_len; } } if (sqltype == SQL_BINARY || sqltype == SQL_VARBINARY || sqltype == SQL_LONGVARBINARY) { ctype = SQL_C_BINARY; } else { ctype = SQL_C_CHAR; } P = emalloc(sizeof(*P)); param->driver_data = P; P->len = 0; /* is re-populated each EXEC_PRE */ P->outbuf = NULL; P->is_unicode = pdo_odbc_sqltype_is_unicode(S, sqltype); if (P->is_unicode) { /* avoid driver auto-translation: we'll do it ourselves */ ctype = SQL_C_BINARY; } if ((param->param_type & PDO_PARAM_INPUT_OUTPUT) == PDO_PARAM_INPUT_OUTPUT) { P->paramtype = SQL_PARAM_INPUT_OUTPUT; } else if (param->max_value_len <= 0) { P->paramtype = SQL_PARAM_INPUT; } else { P->paramtype = SQL_PARAM_OUTPUT; } if (P->paramtype != SQL_PARAM_INPUT) { if (PDO_PARAM_TYPE(param->param_type) != PDO_PARAM_NULL) { /* need an explicit buffer to hold result */ P->len = param->max_value_len > 0 ? param->max_value_len : precision; if (P->is_unicode) { P->len *= 2; } P->outbuf = emalloc(P->len + (P->is_unicode ? 2:1)); } } if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->paramtype != SQL_PARAM_INPUT) { pdo_odbc_stmt_error("Can't bind a lob for output"); return 0; } rc = SQLBindParameter(S->stmt, (SQLUSMALLINT) param->paramno+1, P->paramtype, ctype, sqltype, precision, scale, P->paramtype == SQL_PARAM_INPUT ? (SQLPOINTER)param : P->outbuf, P->len, &P->len ); if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { return 1; } pdo_odbc_stmt_error("SQLBindParameter"); return 0; } case PDO_PARAM_EVT_EXEC_PRE: P = param->driver_data; if (!Z_ISREF(param->parameter)) { parameter = ¶m->parameter; } else { parameter = Z_REFVAL(param->parameter); } if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) { if (Z_TYPE_P(parameter) == IS_RESOURCE) { php_stream *stm; php_stream_statbuf sb; php_stream_from_zval_no_verify(stm, parameter); if (!stm) { return 0; } if (0 == php_stream_stat(stm, &sb)) { if (P->outbuf) { int len, amount; char *ptr = P->outbuf; char *end = P->outbuf + P->len; P->len = 0; do { amount = end - ptr; if (amount == 0) { break; } if (amount > 8192) amount = 8192; len = php_stream_read(stm, ptr, amount); if (len == 0) { break; } ptr += len; P->len += len; } while (1); } else { P->len = SQL_LEN_DATA_AT_EXEC(sb.sb.st_size); } } else { if (P->outbuf) { P->len = 0; } else { P->len = SQL_LEN_DATA_AT_EXEC(0); } } } else { convert_to_string(parameter); if (P->outbuf) { P->len = Z_STRLEN_P(parameter); memcpy(P->outbuf, Z_STRVAL_P(parameter), P->len); } else { P->len = SQL_LEN_DATA_AT_EXEC(Z_STRLEN_P(parameter)); } } } else if (Z_TYPE_P(parameter) == IS_NULL || PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL) { P->len = SQL_NULL_DATA; } else { convert_to_string(parameter); if (P->outbuf) { zend_ulong ulen; switch (pdo_odbc_utf82ucs2(stmt, P->is_unicode, Z_STRVAL_P(parameter), Z_STRLEN_P(parameter), &ulen)) { case PDO_ODBC_CONV_FAIL: case PDO_ODBC_CONV_NOT_REQUIRED: P->len = Z_STRLEN_P(parameter); memcpy(P->outbuf, Z_STRVAL_P(parameter), P->len); break; case PDO_ODBC_CONV_OK: P->len = ulen; memcpy(P->outbuf, S->convbuf, P->len); break; } } else { P->len = SQL_LEN_DATA_AT_EXEC(Z_STRLEN_P(parameter)); } } return 1; case PDO_PARAM_EVT_EXEC_POST: P = param->driver_data; if (P->outbuf) { zend_ulong ulen; char *srcbuf; zend_ulong srclen = 0; if (Z_ISREF(param->parameter)) { parameter = Z_REFVAL(param->parameter); } else { parameter = ¶m->parameter; } zval_ptr_dtor(parameter); ZVAL_NULL(parameter); switch (P->len) { case SQL_NULL_DATA: break; default: switch (pdo_odbc_ucs22utf8(stmt, P->is_unicode, P->outbuf, P->len, &ulen)) { case PDO_ODBC_CONV_FAIL: /* something fishy, but allow it to come back as binary */ case PDO_ODBC_CONV_NOT_REQUIRED: srcbuf = P->outbuf; srclen = P->len; break; case PDO_ODBC_CONV_OK: srcbuf = S->convbuf; srclen = ulen; break; } ZVAL_NEW_STR(parameter, zend_string_alloc(srclen, 0)); memcpy(Z_STRVAL_P(parameter), srcbuf, srclen); Z_STRVAL_P(parameter)[Z_STRLEN_P(parameter)] = '\0'; } } return 1; } } return 1; }
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; }
PassFail TestSQLDescribeParam(TestInfo *pTestInfo, int MX_MP_SPECIFIC) { TEST_DECLARE; char Heading[MAX_STRING_SIZE]; RETCODE returncode; SQLHANDLE henv; SQLHANDLE hdbc; SQLHANDLE hstmt; SWORD numparam; UWORD icol; SWORD st, SQLType[] = { SQL_CHAR,SQL_VARCHAR,SQL_DECIMAL,SQL_NUMERIC,SQL_SMALLINT,SQL_INTEGER,SQL_REAL, SQL_DOUBLE,SQL_DOUBLE,SQL_DATE,SQL_TIME,SQL_TIMESTAMP,SQL_BIGINT,SQL_LONGVARCHAR, SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC }; // SQL_DOUBLE for SQL_FLOAT MX limitation //SQL_BIGINT replaced by SQL_NUMERIC in MX SWORD MPSQLType[] = { SQL_CHAR,SQL_VARCHAR,SQL_DECIMAL,SQL_NUMERIC,SQL_SMALLINT,SQL_INTEGER,SQL_REAL, SQL_FLOAT,SQL_FLOAT,SQL_DATE,SQL_TIME,SQL_TIMESTAMP,SQL_BIGINT,SQL_LONGVARCHAR, SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC,SQL_NUMERIC }; SQLULEN cp; SQLULEN ColPrec[] = {10,10,10,10,5,10,7,15,15,10,8,26,19,2000,19,19,128,128,128,10,18,30}; SQLULEN MPColPrec[] = {10,10,10,10,5,10,7,15,15,10,8,26,19,10,19,19,128,128,128,10,18,30}; SWORD cs, cnull, ColScale[] = {0,0,5,5,0,0,0,0,0,0,0,6,0,0,0,6,0,128,64,5,5,10}; CHAR *DropStr[] = {"--","--","endloop"}; CHAR *CrtStr[] = {"--", "--", "endloop"}; CHAR *MPCrtStr[] = {"--", "--", "endloop"}; CHAR *ExecDirStr[] = {"--","--","--","--","--","--","--","--","--","--","endloop"}; char TempType1[50],TempType2[50]; SWORD ColNullable[] = {SQL_NULLABLE,SQL_NO_NULLS,SQL_NULLABLE,SQL_NO_NULLS,SQL_NULLABLE,SQL_NO_NULLS,SQL_NULLABLE,SQL_NO_NULLS,SQL_NULLABLE,SQL_NO_NULLS}; CHAR *TestCase[] = { "before preparing stmt ", "endloop" }; SQLUSMALLINT i = 0, l = 0; //=========================================================================================================== var_list_t *var_list; var_list = load_api_vars("SQLDescribeParam", charset_file); if (var_list == NULL) return FAILED; //=====================Modified for Longvarchar Changes======================================================== if(!pTestInfo->bLongOn) { int i = 0; char *noLong = "SQL_VARCHAR"; SWORD iNoLong = SQL_VARCHAR; SQLType[13] = iNoLong; MPSQLType[13] = iNoLong; } //=====================Modified for Longvarchar Changes======================================================== //print_list(var_list); DropStr[0] = var_mapping("SQLDescribeParam_DropStr_1", var_list); DropStr[1] = var_mapping("SQLDescribeParam_DropStr_2", var_list); CrtStr[0] = var_mapping("SQLDescribeParam_CrtStr_1", var_list); CrtStr[1] = var_mapping("SQLDescribeParam_CrtStr_2", var_list); MPCrtStr[0] = var_mapping("SQLDescribeParam_MPCrtStr_1", var_list); MPCrtStr[1] = var_mapping("SQLDescribeParam_MPCrtStr_2", var_list); ExecDirStr[0] = var_mapping("SQLDescribeParam_ExecDirStr_1", var_list); ExecDirStr[1] = var_mapping("SQLDescribeParam_ExecDirStr_2", var_list); ExecDirStr[2] = var_mapping("SQLDescribeParam_ExecDirStr_3", var_list); ExecDirStr[3] = var_mapping("SQLDescribeParam_ExecDirStr_4", var_list); ExecDirStr[4] = var_mapping("SQLDescribeParam_ExecDirStr_5", var_list); ExecDirStr[5] = var_mapping("SQLDescribeParam_ExecDirStr_6", var_list); ExecDirStr[6] = var_mapping("SQLDescribeParam_ExecDirStr_7", var_list); ExecDirStr[7] = var_mapping("SQLDescribeParam_ExecDirStr_8", var_list); ExecDirStr[8] = var_mapping("SQLDescribeParam_ExecDirStr_9", var_list); ExecDirStr[9] = var_mapping("SQLDescribeParam_ExecDirStr_10", var_list); //================================================================================================= if(isUCS2) { LogMsg(NONE,"Setup for UCS2 mode testing: ColPrec has to be doubled\n"); l = sizeof(SQLType)/sizeof(SQLType[0]); while(i < l) { if(SQLType[i] == SQL_CHAR) { //SQLType[i] = SQL_WCHAR; ColPrec[i] *= 2; //--> This is in character, so no need to double } else if (SQLType[i] == SQL_VARCHAR) { //SQLType[i] = SQL_WVARCHAR; ColPrec[i] *= 2; //--> This is in character, so no need to double } else if (SQLType[i] == SQL_LONGVARCHAR) { //SQLType[i] = SQL_WLONGVARCHAR; ColPrec[i] *= 2; //--> This is in character, so no need to double } else { } i++; } i = 0; l = sizeof(MPSQLType)/sizeof(MPSQLType[0]); while(i < l) { if(MPSQLType[i] == SQL_CHAR) { //MPSQLType[i] = SQL_WCHAR; MPColPrec[i] *= 2; //--> This is in character, so no need to double } else if (MPSQLType[i] == SQL_VARCHAR) { //MPSQLType[i] = SQL_WVARCHAR; MPColPrec[i] *= 2; //--> This is in character, so no need to double } else if (MPSQLType[i] == SQL_LONGVARCHAR) { //MPSQLType[i] = SQL_WLONGVARCHAR; MPColPrec[i] *= 2; //--> This is in character, so no need to double } else { } i++; } i = 0; l = 0; } //=========================================================================================================== if (MX_MP_SPECIFIC == MX_SPECIFIC) LogMsg(LINEBEFORE+SHORTTIMESTAMP,"Begin testing API => MX Specific SQLDescribeParam | SQLDescribeParam | desparam.c\n"); else LogMsg(LINEBEFORE+SHORTTIMESTAMP,"Begin testing API => MP Specific SQLDescribeParam | SQLDescribeParam | desparam.c\n"); TEST_INIT; TESTCASE_BEGIN("Setup for SQLDescribeParam tests\n"); if(!FullConnect(pTestInfo)){ LogMsg(NONE,"Unable to connect\n"); TEST_FAILED; TEST_RETURN; } henv = pTestInfo->henv; hdbc = pTestInfo->hdbc; hstmt = (SQLHANDLE)pTestInfo->hstmt; returncode = SQLAllocStmt((SQLHANDLE)hdbc, &hstmt); if(!CHECKRC(SQL_SUCCESS,returncode,"SQLAllocStmt")) { LogAllErrors(henv,hdbc,hstmt); TEST_FAILED; TEST_RETURN; } i = 0; while (_stricmp(DropStr[i],"endloop") != 0) { SQLExecDirect(hstmt,(SQLCHAR*)DropStr[i],SQL_NTS); /* cleanup */ i++; } i = 0; if (MX_MP_SPECIFIC == MX_SPECIFIC) { while (_stricmp(CrtStr[i],"endloop") != 0) { returncode = SQLExecDirect(hstmt,(SQLCHAR*)CrtStr[i],SQL_NTS); /* create table */ if(!CHECKRC(SQL_SUCCESS,returncode,"SQLExecDirect")) { LogAllErrors(henv,hdbc,hstmt); TEST_FAILED; TEST_RETURN; } //LogMsg(NONE,"%s\n", CrtStr[i]); i++; } } else { while (_stricmp(MPCrtStr[i],"endloop") != 0) { returncode = SQLExecDirect(hstmt,(SQLCHAR*)MPCrtStr[i],SQL_NTS); /* create table */ if(!CHECKRC(SQL_SUCCESS,returncode,"SQLExecDirect")) { LogAllErrors(henv,hdbc,hstmt); TEST_FAILED; TEST_RETURN; } //LogMsg(NONE,"%s\n", MPCrtStr[i]); i++; } } TESTCASE_END; // end of setup l = 0; while (_stricmp(TestCase[l],"endloop") != 0) { i = 0; while (_stricmp(ExecDirStr[i],"endloop") != 0) { //================================================================================== sprintf(Heading,"SQLDescribeParam: Test #%d.%d\n",l,i); TESTCASE_BEGIN(Heading); returncode = SQLPrepare(hstmt,(SQLCHAR*)ExecDirStr[i], SQL_NTS); //LogMsg(NONE,"%s\n", ExecDirStr[i]); if(!CHECKRC(SQL_SUCCESS,returncode,"SQLPrepare")) { LogAllErrors(henv,hdbc,hstmt); TEST_FAILED; } else { returncode=SQLNumParams(hstmt, &numparam); if(!CHECKRC(SQL_SUCCESS,returncode,"SQLNumResultCols")) { LogAllErrors(henv,hdbc,hstmt); TEST_FAILED; } //LogMsg(NONE,"SQLNumParams returns %d\n", numparam); for (icol = 1; icol <= numparam; icol++) { LogMsg(LINEBEFORE,"SQLDescribeParam: checking Column #%d\n",icol); returncode = SQLDescribeParam(hstmt,icol,&st,&cp,&cs,&cnull); if(!CHECKRC(SQL_SUCCESS,returncode,"SQLDescribeParam")) { TEST_FAILED; LogAllErrors(henv,hdbc,hstmt); } if (MX_MP_SPECIFIC == MX_SPECIFIC) { if ((st==SQLType[icol-1]) && (cp==ColPrec[icol-1]) && (cs==ColScale[icol-1]) && (cnull==ColNullable[i])) { //LogMsg(NONE,"SQLType expect: %s and actual: %s are matched\n", // SQLTypeToChar(SQLType[icol-1],TempType1),SQLTypeToChar(st,TempType2)); //LogMsg(NONE,"ColPrec expect: %d and actual: %d are matched\n",ColPrec[icol-1],cp); //LogMsg(NONE,"ColScale expect: %d and actual: %d are matched\n",ColScale[icol-1],cs); //LogMsg(NONE,"ColNullable expect: %s and actual: %s are matched\n\n", // SQLNullToChar(ColNullable[i],TempType1),SQLNullToChar(cnull,TempType2)); } else { TEST_FAILED; if (st != SQLType[icol-1]) LogMsg(ERRMSG,"SQLType expect: %s and actual: %s are not matched\n",SQLTypeToChar(SQLType[icol-1],TempType1),SQLTypeToChar(st,TempType2)); if (cp != ColPrec[icol-1]) LogMsg(ERRMSG,"ColPrec expect: %d and actual: %d are not matched\n",ColPrec[icol-1],cp); if (cs != ColScale[icol-1]) LogMsg(ERRMSG,"ColScale expect: %d and actual: %d are not matched\n",ColScale[icol-1],cs); if (cnull != ColNullable[i]) LogMsg(ERRMSG,"ColNullable expect: %s and actual: %s are not matched\n\n",SQLNullToChar(ColNullable[i],TempType1),SQLNullToChar(cnull,TempType2)); } } else { if ((st==MPSQLType[icol-1]) && (cp==MPColPrec[icol-1]) && (cs==ColScale[icol-1]) && (cnull==ColNullable[i])) { //LogMsg(NONE,"SQLType expect: %s and actual: %s are matched\n", // SQLTypeToChar(MPSQLType[icol-1],TempType1),SQLTypeToChar(st,TempType2)); //LogMsg(NONE,"ColPrec expect: %d and actual: %d are matched\n",MPColPrec[icol-1],cp); //LogMsg(NONE,"ColScale expect: %d and actual: %d are matched\n",ColScale[icol-1],cs); //LogMsg(NONE,"ColNullable expect: %s and actual: %s are matched\n\n", // SQLNullToChar(ColNullable[i],TempType1),SQLNullToChar(cnull,TempType2)); } else { TEST_FAILED; if (st != MPSQLType[icol-1]) LogMsg(ERRMSG,"SQLType expect: %s and actual: %s are not matched\n",SQLTypeToChar(MPSQLType[icol-1],TempType1),SQLTypeToChar(st,TempType2)); if (cp != MPColPrec[icol-1]) LogMsg(ERRMSG,"ColPrec expect: %d and actual: %d are not matched\n",MPColPrec[icol-1],cp); if (cs != ColScale[icol-1]) LogMsg(ERRMSG,"ColScale expect: %d and actual: %d are not matched\n",ColScale[icol-1],cs); if (cnull != ColNullable[i]) LogMsg(ERRMSG,"ColNullable expect: %s and actual: %s are not matched\n\n",SQLNullToChar(ColNullable[i],TempType1),SQLNullToChar(cnull,TempType2)); } } } /* end icol loop */ } SQLFreeStmt(hstmt,SQL_CLOSE); i++; TESTCASE_END; } l++; } i = 0; while (_stricmp(DropStr[i],"endloop") != 0) { SQLExecDirect(hstmt,(SQLCHAR*)DropStr[i],SQL_NTS); /* cleanup */ i++; } FullDisconnect(pTestInfo); LogMsg(SHORTTIMESTAMP+LINEAFTER,"End testing API => MX Specific SQLDescribeParam.\n"); free_list(var_list); TEST_RETURN; }
static BOOL kpc_bindparameter(ATOMID idfName, WORD h, LPFETCH lpFetch, int nParam, ATOMID idMode, WORD wType, OBJECTID idObj, ATOMID idSlot, BOOL bLive) { WORD wMode; WORD sqlType = SQL_LONGVARCHAR, scale = 0, nullable = SQL_NO_NULLS; DWORD colDef = RET_BUFFER_LEN - 1; LPPARAM lpParams, lpParam; LPDESC lpDesc; WORD wNumParams = 0; DWORD dwLen; RETCODE code; if (idMode == Symbol(INPUT)) wMode = SQL_PARAM_INPUT; else if (idMode == Symbol(OUTPUT)) wMode = SQL_PARAM_OUTPUT; else if (idMode == Symbol(INPUT_OUTPUT)) wMode = SQL_PARAM_INPUT_OUTPUT; code = SQLDescribeParam(lpFetch->hstmt, nParam, &sqlType, &colDef, &scale, &nullable); switch (code) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: break; case SQL_INVALID_HANDLE: return KPC_HANDLE_ERROR(IDE_INVALID_HANDLE, h); default: sql_error(idfName, SQL_NULL_HDBC, lpFetch->hstmt); if (!stricmp(sqlstate, "IM001")) { if (nParam < 1) return KPC_ERROR(IDE_OUTOF_RANGE, KppAddAtomInt(nParam)); if (!num_params(idfName, h, lpFetch->hstmt, &wNumParams)) return ERROR; if (nParam > wNumParams) return KPC_ERROR(IDE_OUTOF_RANGE, KppAddAtomInt(nParam)); sqlType = SQL_LONGVARCHAR; colDef = RET_BUFFER_LEN - 1; nullable = SQL_NO_NULLS; } else return ERROR; } if (!lpFetch->params) { if (!wNumParams && !num_params(idfName, h, lpFetch->hstmt, &wNumParams)) return ERROR; lpParams = calloc(sizeof(PARAM), wNumParams); if (!lpParams) return KPC_ERROR(IDE_OUTOF_MEMORY, NULLID); } else lpParams = lpFetch->params; lpParam = lpParams + nParam - 1; lpDesc = &lpParam->desc; lpDesc->sqlType = sqlType; lpDesc->colDef = colDef; lpDesc->scale = scale; lpDesc->nullable = nullable; if (lpFetch->wXParamRows) { lpDesc->pdwLen = calloc(sizeof(DWORD), lpFetch->wXParamRows + 1); if (!lpDesc->pdwLen) return KPC_ERROR(IDE_OUTOF_MEMORY, NULLID); } else lpDesc->pdwLen = &lpDesc->dwLen; if (!fill_bind(idfName, lpDesc, &lpParam->data, lpFetch->wXParamRows, &dwLen)) { free_params(lpParams, lpFetch->wNumParams); return ERROR; } else { lpParam->wMode = wMode; lpParam->wType = wType; lpParam->idObj = idObj; lpParam->idSlot = idSlot; lpDesc->colDef = dwLen; lpFetch->wNumParams = wNumParams; lpFetch->params = lpParams; if (bLive) { int i = -1; while (++i <= lpFetch->wXParamRows) lpDesc->pdwLen[i] = SQL_LEN_DATA_AT_EXEC(0); } else if (!set_parameter_value(idfName, lpParam, lpFetch->wXParamRows)) return ERROR; } code = SQLBindParameter(lpFetch->hstmt, nParam, wMode, lpDesc->cType, lpDesc->sqlType, lpDesc->colDef, lpDesc->scale, lpDesc->address, dwLen, lpDesc->pdwLen); switch (code) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: lpParam->bound = TRUE; return TRUE; case SQL_INVALID_HANDLE: return KPC_HANDLE_ERROR(IDE_INVALID_HANDLE, h); default: return sql_error(idfName, SQL_NULL_HDBC, lpFetch->hstmt); } }
static int odbc_dispatch22(void) { unsigned long retval; PWord rval; int rtype; PWord arg1; int type1; PWord arg2; int type2; PWord arg3; int type3; PWord arg4; int type4; PWord arg5; int type5; PWord arg6; int type6; PWord arg7; int type7; PWord arg8; int type8; PI_getan(&arg1,&type1,1); if (type1 != PI_INT) if (!CI_get_integer((unsigned long *)&arg1,type1)) PI_FAIL; PI_getan(&arg2,&type2,2); if (type2 != PI_INT) if (!CI_get_integer((unsigned long *)&arg2,type2)) PI_FAIL; PI_getan(&arg3,&type3,3); if (type3 != PI_INT) if (!CI_get_integer((unsigned long *)&arg3,type3)) PI_FAIL; PI_getan(&arg4,&type4,4); if (type4 != PI_INT) if (!CI_get_integer((unsigned long *)&arg4,type4)) PI_FAIL; PI_getan(&arg5,&type5,5); if (type5 != PI_INT) if (!CI_get_integer((unsigned long *)&arg5,type5)) PI_FAIL; PI_getan(&arg6,&type6,6); if (type6 != PI_INT) if (!CI_get_integer((unsigned long *)&arg6,type6)) PI_FAIL; PI_getan(&arg7,&type7,7); if (type7 != PI_INT) if (!CI_get_integer((unsigned long *)&arg7,type7)) PI_FAIL; PI_getan(&arg8,&type8,8); switch(arg1) { case 0: retval = (unsigned long) SQLDescribeParam(((SQLHSTMT ) arg2),((SQLUSMALLINT ) arg3),((SQLSMALLINT * ) arg4),((SQLUINTEGER * ) arg5),((SQLSMALLINT * ) arg6),((SQLSMALLINT * ) arg7)); break; case 1: retval = (unsigned long) SQLGetDescField(((SQLHDESC ) arg2),((SQLSMALLINT ) arg3),((SQLSMALLINT ) arg4),((SQLPOINTER ) arg5),((SQLINTEGER ) arg6),((SQLINTEGER * ) arg7)); break; case 2: retval = (unsigned long) SQLGetData(((SQLHSTMT ) arg2),((SQLUSMALLINT ) arg3),((SQLSMALLINT ) arg4),((SQLPOINTER ) arg5),((SQLINTEGER ) arg6),((SQLINTEGER * ) arg7)); break; case 3: retval = (unsigned long) SQLBindCol(((SQLHSTMT ) arg2),((SQLUSMALLINT ) arg3),((SQLSMALLINT ) arg4),((SQLPOINTER ) arg5),((SQLINTEGER ) arg6),((SQLINTEGER * ) arg7)); break; default: PI_FAIL; } PI_makedouble(&rval,&rtype,(double) retval); if (PI_unify(arg8,type8,rval,rtype)) PI_SUCCEED; PI_FAIL; }
void ODBCHandler::describeParameter(const char* sqlProc,int parameterIndex) { SQLHSTMT stmt; SQLRETURN ret; SQLRETURN ret2; SQLSMALLINT columns; /* number of columns in result-set */ int row = 0; if (ODBC_env != SQL_NULL_HANDLE || connected != 0) { SQLCHAR Statement[100]; SQLSMALLINT NumParams, i, DataType, DecimalDigits, Nullable; SQLULEN ParamSize; SQLHSTMT hstmt; // Prompt the user for an SQL statement and prepare it. //GetSQLStatement(Statement); // SQLPrepare(hstmt, sqlProc, SQL_NTS); // Check to see if there are any parameters. If so, process them. SQLNumParams(hstmt, &NumParams); if (NumParams) { // Allocate memory for three arrays. The first holds pointers to buffers in which // each parameter value will be stored in character form. The second contains the // length of each buffer. The third contains the length/indicator value for each // parameter. //SQLPOINTER * PtrArray = (SQLPOINTER *) malloc(NumParams * sizeof(SQLPOINTER)); // SQLINTEGER * BufferLenArray = (SQLINTEGER *) malloc(NumParams * sizeof(SQLINTEGER)); //SQLINTEGER * LenOrIndArray = (SQLINTEGER *) malloc(NumParams * sizeof(SQLINTEGER)); for (i = 0; i < NumParams; i++) { // Describe the parameter. SQLDescribeParam(hstmt, i + 1, &DataType, &ParamSize, &DecimalDigits, &Nullable); // Call a helper function to allocate a buffer in which to store the parameter // value in character form. The function determines the size of the buffer from // the SQL data type and parameter size returned by SQLDescribeParam and returns // a pointer to the buffer and the length of the buffer. //AllocParamBuffer(DataType, ParamSize, &PtrArray[i], &BufferLenArray[i]); // Bind the memory to the parameter. Assume that we only have input parameters. /* SQLBindParameter(hstmt, i + 1, SQL_PARAM_INPUT, SQL_C_CHAR, DataType, ParamSize, DecimalDigits, PtrArray[i], BufferLenArray[i], &LenOrIndArray[i]); */ // Prompt the user for the value of the parameter and store it in the memory // allocated earlier. For simplicity, this function does not check the value // against the information returned by SQLDescribeParam. Instead, the driver does // this when the statement is executed. //GetParamValue(PtrArray[i], BufferLenArray[i], &LenOrIndArray[i]); } } // Execute the statement. //SQLExecute(hstmt); // Process the statement further, such as retrieving results (if any) and closing the // cursor (if any). Code not shown. // Free the memory allocated for each parameter and the memory allocated for the arrays // of pointers, buffer lengths, and length/indicator values. //for (i = 0; i < NumParams; i++) free(PtrArray[i]); //free(PtrArray); //free(BufferLenArray); //free(LenOrIndArray); } }