[freetds] SQLRowCount failing after prepare and execute

ZIGLIO, Frediano, VF-IT Frediano.Ziglio at vodafone.com
Tue Feb 17 10:44:43 EST 2004


> 
> Hey Freddy,
> 
> I was thinking about this overnight - an annoying feature of 
> being part of this project - and I had the following thoughts.
> 
> Lets put aside your recent findings with the "two statements 
> in one prepare" for the moment, and get back to the original 
> problem. Matthew reports that SQLRowCount doesn't return the 
> value when called as
> follows:
> 
> SQLPrepare(hstmt, (SQLCHAR *)("UPDATE <table> SET <column> = 
> <value>" ), SQL_NTS); SQLExecute(hstmt); SQLRowCount(hstmt, &rows);
> 
> This is clearly bad news. We should give him the rowcount.
> If we're to do this, it means that we HAVE to read the 
> DONEINPROC token and do something with the row count we get.
> 

Returning only the last valid count in this case seems the better
solution as triggers are executed before your UPDATE. I think this is
the reason of strange (and wrong) MS ODBC behaviour.

> Some questions. If the prepared statement is a SELECT... what 
> does the execute do ? presumably it doesn't fetch the rows... 
> Is it valid to call SQLRowcount directly after the SQLExecute 
> in this circumstance. If so, what is it supposed to return ? 
> it can't return a rowcount as we haven't fetched the rows or 
> read the following DONE token , have we ?
> 

SQLRowCount is expected to return SQL_SUCCESS and -1 rows. SQLRowCount
return valid information after you retrived all rows.

> Isn't it therefore in the programmers arena to decide when 
> it's valid to call SQLRowcount ?
> 

Client should expect that row number is not available just after issuing
the query.

> If the programmer knows they have prepared and executed an 
> UPDATE statement, then calling SQLRowcount afterwards is 
> valid, and it should return a valid value. If the programmer 
> knows they have prepared and executed a SELECT statement then 
> presumably calling SQLRowcount afterwards is meaningless, and 
> is not going to tell them anything, so they shouldn't call it 
> or rely on the results if they do...
> 
> Coming back to your "two statements in one prepare", 
> calling SQLRowcount and the equivalent-function-which-gives-the
> number-of-columns (SQLColcount ?) is bound to be ambiguous in 
> this context. We shouldn't worry that the results we pass 
> back are ambiguous - the programmer shouldn't expect anything 
> else, given what they've done.  
> 

This is why I suggest to return only the last update/delete/insert row
count.

> coming back to solving Matthews problem - we SHOULD read the 
> DONEINPROC token and save any valid "done count" value. and 
> we should return that value when asked. If we were to 
> maintain a "running total" of "done counts" from the 
> DONEINPROC tokens we read, and do the same for the column 
> counts (however they are arrived at) then we would have valid 
> values to return in Matthews case. We would also have 
> something to return in your "two statements in one prepare" 
> case - although it would be (necessarily) ambiguous. I THINK 
> this method might approximate the results you are seeing from 
> the MS ODBC driver...
> 

If we have column count we have all column informations (names, lengths
and so on).

> If we end up adding in rowcounts generated by triggered 
> updates/inserts/deletes - so what ? we would be returning a 
> valid total of the number of records affected by the original 
> statement. It might be worth trying out a simple statement 
> with a trigger attached to the update in your MS ODBC driver 
> to see how that behaves...bet I can guess...
> 
> Hope this helps
> 

I still think to return last row count from update/delete/insert so even
on prepare we can get last delete/insert/update row count. It's a
differect sligth behaviour but more correct. So "select ... delete ..."
return 2 recordset while "delete ... select ..." return just a
recordset.

freddy77



More information about the FreeTDS mailing list