📄 odbc.c
字号:
SQLColumnPrivileges(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR FAR * szTableName, SQLSMALLINT cbTableName, SQLCHAR FAR * szColumnName, SQLSMALLINT cbColumnName){ int retcode; INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "SQLColumnPrivileges(%p, %p, %d, %p, %d, %p, %d, %p, %d)\n", hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName, szColumnName, cbColumnName); retcode = odbc_stat_execute(stmt, "sp_column_privileges ", 4, "O@table_qualifier", szCatalogName, cbCatalogName, "O@table_owner", szSchemaName, cbSchemaName, "O@table_name", szTableName, cbTableName, "P@column_name", szColumnName, cbColumnName); if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) { odbc_col_setname(stmt, 1, "TABLE_CAT"); odbc_col_setname(stmt, 2, "TABLE_SCHEM"); } ODBC_RETURN_(stmt);}#if 0SQLRETURN ODBC_APISQLDescribeParam(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT FAR * pfSqlType, SQLUINTEGER FAR * pcbParamDef, SQLSMALLINT FAR * pibScale, SQLSMALLINT FAR * pfNullable){ tdsdump_log(TDS_DBG_FUNC, "SQLDescribeParam(%p, %d, %p, %p, %p, %p)\n", hstmt, ipar, pfSqlType, pcbParamDef, pibScale, pfNullable); INIT_HSTMT; odbc_errs_add(&stmt->errs, "HYC00", "SQLDescribeParam: function not implemented"); ODBC_RETURN(stmt, SQL_ERROR);}#endifSQLRETURN ODBC_APISQLExtendedFetch(SQLHSTMT hstmt, SQLUSMALLINT fFetchType, SQLROWOFFSET irow, SQLROWSETSIZE FAR * pcrow, SQLUSMALLINT FAR * rgfRowStatus){ SQLRETURN ret; SQLULEN * tmp_rows; SQLUSMALLINT * tmp_status; SQLULEN tmp_size; SQLLEN * tmp_offset; SQLPOINTER tmp_bookmark; SQLULEN bookmark; SQLULEN out_len = 0; INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "SQLExtendedFetch(%p, %d, %d, %p, %p)\n", hstmt, fFetchType, (int)irow, pcrow, rgfRowStatus); if (fFetchType != SQL_FETCH_NEXT && !stmt->dbc->cursor_support) { odbc_errs_add(&stmt->errs, "HY106", NULL); ODBC_RETURN(stmt, SQL_ERROR); } /* save and change IRD/ARD state */ tmp_rows = stmt->ird->header.sql_desc_rows_processed_ptr; stmt->ird->header.sql_desc_rows_processed_ptr = &out_len; tmp_status = stmt->ird->header.sql_desc_array_status_ptr; stmt->ird->header.sql_desc_array_status_ptr = rgfRowStatus; tmp_size = stmt->ard->header.sql_desc_array_size; stmt->ard->header.sql_desc_array_size = stmt->sql_rowset_size; tmp_offset = stmt->ard->header.sql_desc_bind_offset_ptr; stmt->ard->header.sql_desc_bind_offset_ptr = NULL; tmp_bookmark = stmt->attr.fetch_bookmark_ptr; /* SQL_FETCH_BOOKMARK different */ if (fFetchType == SQL_FETCH_BOOKMARK) { bookmark = irow; irow = 0; stmt->attr.fetch_bookmark_ptr = &bookmark; } /* TODO errors are sligthly different ... perhaps it's better to leave DM do this job ?? */ /* TODO check fFetchType can be converted to USMALLINT */ ret = _SQLFetch(stmt, fFetchType, irow); /* restore IRD/ARD */ stmt->ird->header.sql_desc_rows_processed_ptr = tmp_rows; if (pcrow) *pcrow = out_len; stmt->ird->header.sql_desc_array_status_ptr = tmp_status; stmt->ard->header.sql_desc_array_size = tmp_size; stmt->ard->header.sql_desc_bind_offset_ptr = tmp_offset; stmt->attr.fetch_bookmark_ptr = tmp_bookmark; ODBC_RETURN(stmt, ret);}SQLRETURN ODBC_APISQLForeignKeys(SQLHSTMT hstmt, SQLCHAR FAR * szPkCatalogName, SQLSMALLINT cbPkCatalogName, SQLCHAR FAR * szPkSchemaName, SQLSMALLINT cbPkSchemaName, SQLCHAR FAR * szPkTableName, SQLSMALLINT cbPkTableName, SQLCHAR FAR * szFkCatalogName, SQLSMALLINT cbFkCatalogName, SQLCHAR FAR * szFkSchemaName, SQLSMALLINT cbFkSchemaName, SQLCHAR FAR * szFkTableName, SQLSMALLINT cbFkTableName){ int retcode; INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "SQLForeignKeys(%p, %p, %d, %p, %d, %p, %d, %p, %d, %p, %d, %p, %d)\n", hstmt, szPkCatalogName, cbPkCatalogName, szPkSchemaName, cbPkSchemaName, szPkTableName, cbPkTableName, szFkCatalogName, cbFkCatalogName, szFkSchemaName, cbFkSchemaName, szFkTableName, cbFkTableName); retcode = odbc_stat_execute(stmt, "sp_fkeys ", 6, "O@pktable_qualifier", szPkCatalogName, cbPkCatalogName, "O@pktable_owner", szPkSchemaName, cbPkSchemaName, "O@pktable_name", szPkTableName, cbPkTableName, "O@fktable_qualifier", szFkCatalogName, cbFkCatalogName, "O@fktable_owner", szFkSchemaName, cbFkSchemaName, "O@fktable_name", szFkTableName, cbFkTableName); if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) { odbc_col_setname(stmt, 1, "PKTABLE_CAT"); odbc_col_setname(stmt, 2, "PKTABLE_SCHEM"); odbc_col_setname(stmt, 5, "FKTABLE_CAT"); odbc_col_setname(stmt, 6, "FKTABLE_SCHEM"); } ODBC_RETURN_(stmt);}static intodbc_lock_statement(TDS_STMT* stmt){ TDSSOCKET *tds = stmt->dbc->tds_socket; /* FIXME quite bad... two thread can lock the same TDSSOCKET */ if (stmt->dbc->current_statement != NULL && stmt->dbc->current_statement != stmt) { if (!tds || tds->state != TDS_IDLE) { odbc_errs_add(&stmt->errs, "24000", NULL); return 0; } } if (tds) tds->query_timeout = (stmt->attr.query_timeout != DEFAULT_QUERY_TIMEOUT) ? stmt->attr.query_timeout : stmt->dbc->default_query_timeout; stmt->dbc->current_statement = stmt; stmt->cancel_sent = 0; return 1;}SQLRETURN ODBC_APISQLMoreResults(SQLHSTMT hstmt){ TDSSOCKET *tds; TDS_INT result_type; int tdsret; int in_row = 0; SQLUSMALLINT param_status; int token_flags; INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "SQLMoreResults(%p)\n", hstmt); tds = stmt->dbc->tds_socket; /* We already read all results... */ /* TODO cursor */ if (stmt->dbc->current_statement != stmt) ODBC_RETURN(stmt, SQL_NO_DATA); stmt->row_count = TDS_NO_COUNT; stmt->special_row = 0; /* TODO this code is TOO similar to _SQLExecute, merge it - freddy77 */ /* try to go to the next recordset */ if (stmt->row_status == IN_COMPUTE_ROW) { /* FIXME doesn't seem so fine ... - freddy77 */ tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_TRAILING); stmt->row_status = IN_COMPUTE_ROW; in_row = 1; } param_status = SQL_PARAM_SUCCESS; token_flags = (TDS_TOKEN_RESULTS & (~TDS_STOPAT_COMPUTE)) | TDS_RETURN_COMPUTE; if (stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) token_flags |= TDS_RETURN_MSG; for (;;) { result_type = odbc_process_tokens(stmt, token_flags); tdsdump_log(TDS_DBG_INFO1, "SQLMoreResults: result_type=%d, row_count=%" TDS_I64_FORMAT ", lastrc=%d\n", result_type, stmt->row_count, stmt->errs.lastrc); switch (result_type) { case TDS_CMD_DONE: if (stmt->dbc->current_statement == stmt) stmt->dbc->current_statement = NULL;#if 1 /* !UNIXODBC */ tds_free_all_results(tds);#endif odbc_populate_ird(stmt); if (stmt->row_count == TDS_NO_COUNT && !in_row) { stmt->row_status = NOT_IN_ROW; tdsdump_log(TDS_DBG_INFO1, "SQLMoreResults: row_status=%d\n", stmt->row_status); } tdsdump_log(TDS_DBG_INFO1, "SQLMoreResults: row_count=%" TDS_I64_FORMAT ", lastrc=%d\n", stmt->row_count, stmt->errs.lastrc); if (stmt->row_count == TDS_NO_COUNT) { if (stmt->errs.lastrc == SQL_SUCCESS || stmt->errs.lastrc == SQL_SUCCESS_WITH_INFO) ODBC_RETURN(stmt, SQL_NO_DATA); } ODBC_RETURN_(stmt); case TDS_CMD_FAIL: ODBC_SAFE_ERROR(stmt); ODBC_RETURN(stmt, SQL_ERROR); case TDS_COMPUTE_RESULT: switch (stmt->row_status) { /* skip this recordset */ case IN_COMPUTE_ROW: /* TODO here we should set current_results to normal results */ in_row = 1; /* fall through */ /* in normal row, put in compute status */ case AFTER_COMPUTE_ROW: case IN_NORMAL_ROW: case PRE_NORMAL_ROW: stmt->row_status = IN_COMPUTE_ROW; odbc_populate_ird(stmt); ODBC_RETURN_(stmt); case NOT_IN_ROW: /* this should never happen, protocol error */ ODBC_SAFE_ERROR(stmt); ODBC_RETURN(stmt, SQL_ERROR); break; } break; case TDS_ROW_RESULT: if (in_row || (stmt->row_status != IN_NORMAL_ROW && stmt->row_status != PRE_NORMAL_ROW)) { stmt->row_status = PRE_NORMAL_ROW; odbc_populate_ird(stmt); ODBC_RETURN_(stmt); } /* Skipping current result set's rows to access next resultset or proc's retval */ tdsret = tds_process_tokens(tds, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_STOPAT_COMPUTE); /* TODO should we set in_row ?? */ switch (tdsret) { case TDS_CANCELLED: odbc_errs_add(&stmt->errs, "HY008", NULL); ODBC_RETURN(stmt, SQL_ERROR); case TDS_FAIL: ODBC_SAFE_ERROR(stmt); ODBC_RETURN(stmt, SQL_ERROR); } break; case TDS_DONE_RESULT: case TDS_DONEPROC_RESULT: /* FIXME here ??? */ if (!in_row) tds_free_all_results(tds); switch (stmt->errs.lastrc) { case SQL_ERROR: param_status = SQL_PARAM_ERROR; break; case SQL_SUCCESS_WITH_INFO: param_status = SQL_PARAM_SUCCESS_WITH_INFO; break; } if (stmt->curr_param_row < stmt->num_param_rows) { if (stmt->ipd->header.sql_desc_array_status_ptr) stmt->ipd->header.sql_desc_array_status_ptr[stmt->curr_param_row] = param_status; ++stmt->curr_param_row; if (stmt->ipd->header.sql_desc_rows_processed_ptr) *stmt->ipd->header.sql_desc_rows_processed_ptr = stmt->curr_param_row; } if (stmt->curr_param_row < stmt->num_param_rows) {#if 0 if (stmt->errs.lastrc == SQL_SUCCESS_WITH_INFO) found_info = 1; if (stmt->errs.lastrc == SQL_ERROR) found_error = 1;#endif stmt->errs.lastrc = SQL_SUCCESS; param_status = SQL_PARAM_SUCCESS; break; } odbc_populate_ird(stmt); ODBC_RETURN_(stmt); break; /* * TODO test flags ? check error and change result ? * see also other DONEINPROC handle (below) */ case TDS_DONEINPROC_RESULT: if (in_row) { odbc_populate_ird(stmt); ODBC_RETURN_(stmt); } /* TODO perhaps it can be a problem if SET NOCOUNT ON, test it */ tds_free_all_results(tds); odbc_populate_ird(stmt); break; /* do not stop at metadata, an error can follow... */ case TDS_ROWFMT_RESULT: if (in_row) { odbc_populate_ird(stmt); ODBC_RETURN_(stmt); } stmt->row = 0; stmt->row_count = TDS_NO_COUNT; /* we expect a row */ stmt->row_status = PRE_NORMAL_ROW; in_row = 1; break; case TDS_MSG_RESULT: if (!in_row) { tds_free_all_results(tds); odbc_populate_ird(stmt); } in_row = 1; break; } } ODBC_RETURN(stmt, SQL_ERROR);}SQLRETURN ODBC_APISQLNativeSql(SQLHDBC hdbc, SQLCHAR FAR * szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStrMax, SQLINTEGER FAR * pcbSqlStr){ SQLRETURN ret = SQL_SUCCESS; DSTR query; INIT_HDBC; tdsdump_log(TDS_DBG_FUNC, "SQLNativeSql(%p, %s, %d, %p, %d, %p)\n", hdbc, szSqlStrIn, (int)cbSqlStrIn, szSqlStr, (int)cbSqlStrMax, pcbSqlStr); tds_dstr_init(&query);#ifdef TDS_NO_DM if (!szSqlStrIn || !IS_VALID_LEN(cbSqlStrIn)) { odbc_errs_add(&dbc->errs, "HY009", NULL); ODBC_RETURN(dbc, SQL_ERROR); }#endif if (!tds_dstr_copyn(&query, (const char *) szSqlStrIn, odbc_get_string_size(cbSqlStrIn, szSqlStrIn))) { odbc_errs_add(&dbc->errs, "HY001", NULL); ODBC_RETURN(dbc, SQL_ERROR); } /* TODO support not null terminated in native_sql */ native_sql(dbc, tds_dstr_buf(&query)); ret = odbc_set_string_i(szSqlStr, cbSqlStrMax, pcbSqlStr, tds_dstr_cstr(&query), -1); tds_dstr_free(&query); ODBC_RETURN(dbc, ret);}SQLRETURN ODBC_APISQLNumParams(SQLHSTMT hstmt, SQLSMALLINT FAR * pcpar){ INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "SQLNumParams(%p, %p)\n", hstmt, pcpar); *pcpar = stmt->param_count; ODBC_RETURN_(stmt);}SQLRETURN ODBC_APISQLParamOptions(SQLHSTMT hstmt, SQLULEN crow, SQLULEN FAR * pirow){ SQLRETURN res; tdsdump_log(TDS_DBG_FUNC, "SQLParamOptions(%p, %lu, %p)\n", hstmt, (unsigned long int)crow, pirow); /* emulate for ODBC 2 DM */ res = _SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, pirow, 0); if (res != SQL_SUCCESS) return res; return _SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) (TDS_INTPTR) crow, 0);}SQLRETURN ODBC_APISQLPrimaryKeys(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR FAR * szTableName, SQLSMALLINT cbTableName){ int retcode; INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "SQLPrimaryKeys(%p, %p, %d, %p, %d, %p, %d)\n", hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName); retcode = odbc_stat_execute(stmt, "sp_pkeys ", 3, "O@table_qualifier", szCatalogName, cbCatalogName, "O@table_owner", szSchemaName, cbSchemaName, "O@table_name", szTableName, cbTableName); if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) { odbc_col_setname(stmt, 1, "TABLE_CAT"); odbc_col_setname(stmt, 2, "TABLE_SCHEM"); } ODBC_RETURN_(stmt);}SQLRETURN ODBC_APISQLProcedureColumns(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR FAR * szProcName, SQLSMALLINT cbProcName, SQLCHAR FAR * szColumnName, SQLSMALLINT cbColumnName){ int retcode; INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "SQLProcedureColumns(%p, %p, %d, %p, %d, %p, %d, %p, %d)\n", hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szProcName, cbProcName, szColumnName, cbColumnName); retcode = odbc_stat_execute(stmt, "sp_sproc_columns ", 4, "O@procedure_qualifier", szCatalogName, cbCatalogName, "P@procedure_owner", szSchemaName, cbSchemaName, "P@procedure_name", szProcName, cbProcName, "P@column_name", szColumnName, cbColumnName); if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) { odbc_col_setname(stmt, 1, "PROCEDURE_CAT"); odbc_col_setname(stmt, 2, "PROCEDURE_SCHEM"); odbc_col_setname(stmt, 8, "COLUMN_SIZE"); odbc_col_setname(stmt, 9, "BUFFER_LENGTH"); odbc_col_setname(stmt, 10, "DECIMAL_DIGITS"); odbc_col_setname(stmt, 11, "NUM_PREC_RADIX"); } ODBC_RETURN_(stmt);}SQLRETURN ODBC_APISQLProcedures(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR FAR * szProcName, SQLSMALLINT cbProcName){ int retcode; INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "SQLProcedures(%p, %p, %d, %p, %d, %p, %d)\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -