Skip to Content.
Sympa Menu

freetds - [freetds] ODBC returns spurious errors

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Lowden, James K" <LowdenJK AT bernstein.com>
  • To: "TDS Development Group" <freetds AT lists.ibiblio.org>
  • Subject: [freetds] ODBC returns spurious errors
  • Date: Mon, 1 Mar 2004 17:49:26 -0500

I have a fairly well defined problem with DBI::ODBC using unixODBC-2.2.6 and
0.62.1.

If the script below is run, this is the output:

jklowden@dec050$ ./dbi_fail
./dbi_fail: Executing: "delete testdb..a"
./dbi_fail: Execution completed successfully.
./dbi_fail: Executing: "execute testdb..a_insert 5"
DBD::ODBC::db do failed: (DBD: SQLRowCount failed err=-1) at ./dbi_fail line
11.
./dbi_fail: Execution completed successfully.
DBD::ODBC::st execute failed: [unixODBC][FreeTDS][SQL Server]Invalid cursor
state (SQL-24000)(DBD: st_execute/SQLRowCount err=-1) at ./dbi_fail line 26.
err was set at ./dbi_fail line 27.
DBD::ODBC::st fetchrow failed: (DBD: no select statement currently executing
err=-1) at ./dbi_fail line 28.
5
7

IOW, by setting PrintError to 1, we get back all sorts of ominous error
messages. The functions don't fail (don't return undef), but they set "err"
and "errstr" and print them if PrintError is true. As you can see from the
output, they actually *succeed*: the rows are inserted. They just make a lot
of whiney noises, like a cranky two year old after a long day at the mall.

The source of the these messages is the FreeTDS ODBC driver, specifically
_SQLRowCount(SQLHSTMT hstmt, SQLINTEGER FAR * pcrow) in src/odbc/odbc.c:3055.
It has this test:

/* test is this is current statement */
if (stmt->dbc->current_statement != stmt) {
odbc_errs_add(&stmt->errs, "24000", NULL, NULL);
ODBC_RETURN(stmt, SQL_ERROR);
}

I don't know anything about this part of the driver, much less why
"stmt->dbc->current_statement != stmt". It looks to me like the bookkeeping
is wrong, though, because the wire data are OK and the thing actually
succeeds, despite its protestations.

Can anyone bail me out? Please?

More or less interesting details follow. Thanks for any help.

--jkl


Here's the interesting part of the log:

17:20:50.675701 tds_put_string converting 17 bytes of "delete testdb..a"
17:20:50.675885 tds_put_string wrote 34 bytes
Sending packet @ 17:20:50.675987
0000 01 01 00 2a 00 00 01 00-64 00 65 00 6c 00 65 00 |...*.... d.e.l.e.|
0010 74 00 65 00 20 00 20 00-74 00 65 00 73 00 74 00 |t.e. . . t.e.s.t.|
0020 64 00 62 00 2e 00 2e 00-61 00 |d.b..... a.|


Received header @ 17:20:50.678075
0000 04 01 00 11 00 39 01 00- |.....9..|


Received packet @ 17:20:50.678339
0000 fd 10 00 c4 00 02 00 00-00 |........ .|


17:20:50.678689 processing result tokens. marker is fd(DONE)
17:20:50.678800 tds_process_end: more_results = 0
was_cancelled = 0
error = 0
done_count_valid = 1
17:20:50.678913 tds_process_end() state set to TDS_IDLE
17:20:50.679006 rows_affected = 2
17:20:50.679219 _SQLRowCount: 3063
SQLFreeHandle(3, 0x81e6500)
17:20:50.681219 tds_put_string converting 26 bytes of "execute
testdb..a_insert 5"
17:20:50.681386 tds_put_string wrote 52 bytes
Sending packet @ 17:20:50.681491
0000 01 01 00 3c 00 00 01 00-65 00 78 00 65 00 63 00 |...<.... e.x.e.c.|
0010 75 00 74 00 65 00 20 00-74 00 65 00 73 00 74 00 |u.t.e. . t.e.s.t.|
0020 64 00 62 00 2e 00 2e 00-61 00 5f 00 69 00 6e 00 |d.b..... a._.i.n.|
0030 73 00 65 00 72 00 74 00-20 00 35 00 |s.e.r.t. .5.|


Received header @ 17:20:50.683615
0000 04 01 00 28 00 39 01 00- |...(.9..|


Received packet @ 17:20:50.683879
0000 ff 11 00 c3 00 01 00 00-00 ff 11 00 c3 00 01 00 |........ ........|
0010 00 00 79 00 00 00 00 fe-00 00 e0 00 01 00 00 00 |..y..... ........|


17:20:50.684292 processing result tokens. marker is ff(DONEINPROC)
17:20:50.684400 tds_process_end: more_results = 1
was_cancelled = 0
error = 0
done_count_valid = 1
17:20:50.684514 rows_affected = 1
17:20:50.684613 processing result tokens. marker is ff(DONEINPROC)
17:20:50.684714 tds_process_end: more_results = 1
was_cancelled = 0
error = 0
done_count_valid = 1
17:20:50.684826 rows_affected = 1
17:20:50.684921 processing result tokens. marker is 79(RETURNSTATUS)
17:20:50.685025 processing result tokens. marker is fe(DONEPROC)
17:20:50.685127 tds_process_end: more_results = 0
was_cancelled = 0
error = 0
done_count_valid = 0
17:20:50.685238 tds_process_end() state set to TDS_IDLE
17:20:50.685332 tds_process_result_tokens() state is COMPLETED
17:20:50.685456 _SQLRowCount: 3063
17:20:50.685606 odbc_errs_add: Invalid cursor state
SQLFreeHandle(3, 0x81e6500)

Perl
----
#! /usr/local/bin/perl
#
use DBI;

sub runsql {
my ($dbh, $sql, $junk);
if ((($dbh, $sql, $junk) = @_) != 2) {
die "$0: runsql: wrong number of parameters\n";
}
print STDOUT qq($0: Executing: "$sql"\n);
$dbh->do($sql)
or die qq($0: Could not execute "$sql": $DBI::errstr);
print STDOUT "$0: Execution completed successfully.\n";
}

my $db = 'testdb';
my $dbh = DBI->connect("DBI:ODBC:svr", "usr", "psswd", {PrintError => 1});

die "Unable for connect to server $DBI::errstr"
unless $dbh;

&runsql($dbh, "delete testdb..a");
&runsql($dbh, "execute testdb..a_insert 5");

my $sth = $dbh->prepare("execute testdb..a_insert 7") or die;
$sth->execute() || warn "execute failed";
warn "err was set" if $sth->err();
while(@dat = $sth->fetchrow) {
print "Connected to: ", join('.', @dat), "\n";
}

$sql = "select * from testdb..a";
my $sth = $dbh->prepare($sql) or die;
my $rc = $sth->execute or die qq($0: Could not execute "$sql": $DBI::errstr);
if($rc) {
while(@dat = $sth->fetchrow) {
print join('\\', @dat), "\n";
}
}

exit;

SQL
---
create table a (a int)
create proc a_insert @a int as insert a values (@a)


-----------------------------------------
The information contained in this transmission may contain privileged and
confidential information and is intended only for the use of the person(s)
named above. If you are not the intended recipient, or an employee or agent
responsible for delivering this message to the intended recipient, any
review, dissemination, distribution or duplication of this communication is
strictly prohibited. If you are not the intended recipient, please contact
the sender immediately by reply e-mail and destroy all copies of the original
message. Please note that we do not accept account orders and/or instructions
by e-mail, and therefore will not be responsible for carrying out such orders
and/or instructions.
If you, as the intended recipient of this message, the purpose of which is to
inform and update our clients, prospects and consultants of developments
relating to our services and products, would not like to receive further
e-mail correspondence from the sender, please "reply" to the sender
indicating your wishes. In the U.S.: 1345 Avenue of the Americas, New York,
NY 10105.





  • [freetds] ODBC returns spurious errors, Lowden, James K, 03/01/2004

Archive powered by MHonArc 2.6.24.

Top of Page