Re: SQLNumResultCols before SQLExecute
Frediano Ziglio <[email protected]>
| Newsgroups | gmane.comp.db.tds.freetds |
|---|---|
| Message-ID | <[email protected]> |
Correct solution is to issue the prepare and read reply from server... As should do... I'll check this out. freddy77 2011/3/12 Dylan Kucera <[email protected]>: > The following post is unrelated to the issue I just posted with respect to > the "handle 0" problem with TDS 8.0 that I just posted. > > I was hoping to get some feedback on a work-around that I created for the > limitation where FreeTDS cannot determine the answer for SQLNumResultCols > after only calling SQLPrepare. As designed, from what I understand, > SQLExecute must be called first. > > I'm working with the Oracle Heterogenous Services database link capability > so I have no ability to change the approach it takes, and in some > scenarios it asks for SQLNumResultCols after only doing a SQLPrepare. > > From what I've observed, I believe I can count on the structure of the > statement where this occurs to be > > SELECT "c1", "c2", ..., "cn" FROM "t1" WHERE ... > > So, assuming there is no reason to believe the database link has chosen > invalid columns (which it won't because it's already confirmed the column > list with sp_columns! It just seems to have obsessive compulsive > disorder!) then counting the commas before the FROM and adding one does > the trick. > > I know it's not the most elegant thing in the world but after doing this I > can use my Oracle Heterogeneous Services database links just fine. For > those who generally work on the FreeTDS code, would you consider putting > something like this into the main code line for those of us wishing to use > FreeTDS in this use case? Would it really be worse than returning 0? > > Perhaps at the least this helps someone else out, though I'd be open to > any cautionary tales if someone has already been down this path. > > in odbc.c, 2 changes: > > 1) Near line 1320: redefine IRD_UPDATE as per another post I found where > someone had a similar problem: > > #define IRD_UPDATE(desc, errs, exit) do { } while(0) > > #if 0 > #define IRD_UPDATE(desc, errs, exit) \ > do { \ > if (desc->type == DESC_IRD && ((TDS_STMT*)desc->parent)->need_reprepare && \ > odbc_update_ird((TDS_STMT*)desc->parent, errs) != SQL_SUCCESS) \ > exit; \ > } while(0) > #endif > > 2) Near line 4425: redefine SQLNumResultCols as follows: > > SQLRETURN ODBC_API > SQLNumResultCols(SQLHSTMT hstmt, SQLSMALLINT FAR * pccol) > { > char *s; > char *p; > long c; > > INIT_HSTMT; > > > tdsdump_log(TDS_DBG_FUNC, "SQLNumResultCols(%p, %p)\n", > hstmt, pccol); > > /* > * 3/15/2001 bsb - DBD::ODBC calls SQLNumResultCols on non-result > * generating queries such as 'drop table' > */ > #if 0 > if (stmt->row_status == NOT_IN_ROW) { > odbc_errs_add(&stmt->errs, "24000", NULL); > ODBC_RETURN(stmt, SQL_ERROR); > } > #endif > IRD_UPDATE(stmt->ird, &stmt->errs, ODBC_RETURN(stmt, SQL_ERROR)); > *pccol = stmt->ird->header.sql_desc_count; > > > if (stmt->ird->header.sql_desc_count == 0) { > tdsdump_log(TDS_DBG_FUNC, "SQLNumResultCols(%p, %p) - Desparate measures - parse from %s\n", > hstmt, pccol, stmt->prepared_query); > s = malloc (strlen(stmt->prepared_query) + 64); > strcpy(s, stmt->prepared_query); > strupr(s); > p = strstr(s, " FROM "); > if (p != 0) { > *p = '\0'; > c = 1; > p = s; > while ((p = strchr(p+1, ',')) != 0) { > ++c; > } > *pccol = c; > } > free(s); > } > > > tdsdump_log(TDS_DBG_FUNC, "SQLNumResultCols(%p, %p) = %d\n", > hstmt, pccol, *pccol); > > > ODBC_RETURN_(stmt); > } > > > _______________________________________________ > FreeTDS mailing list > [email protected] > http://lists.ibiblio.org/mailman/listinfo/freetds > _______________________________________________ FreeTDS mailing list [email protected] http://lists.ibiblio.org/mailman/listinfo/freetds