in reply to DBI Problem?

Well, the problem is solved. In case anyone gets anything like this in the future, I'll detail what I did to resolve it.

First, I found out that DBI has a trace method that I can access. Adding the following line writes out trace information to the filename specified:

# These are the trace level codes # 0 - Trace disabled. # 1 - Trace DBI method calls returning with results or errors. # 2 - Trace method entry with parameters and returning with results. # 3 - As above, adding some high-level information from the driver # and some internal information from the DBI. # 4 - As above, adding more detailed information from the driver. # Also includes DBI mutex information when using threaded Perl. # 5 As above but with more and more obscure information. DBI->trace(3, "trace.txt");
The first argument is the trace level (I find that anything over 3 gives too much information and I can't understand it) and the second argument is the file to write to in append mode.

Running the trace and reading the output revealed that DBI (or DBD::ODBC, I'm not sure which) was trying to force the errant field to be a varchar, despite the field in the database being declared as the text type. On MSSQL Server 7.0, varchar is limited to 8000 characters.

The solution: change use DBI; to

use DBI qw':sql_types';
Then, after I prepared the SQL, but before it's executed, I inserted the following line:
$sth->bind_param($bind_col, $data{'terms'}, SQL_LONGVARCHAR);
$bind_col is the column of the text field (enumeration starts at 1, not zero). $data{'terms'} was the 23,000 character variable, and SQL_LONGVARCHAR forces it to be the text type.

Thanks to everyone for your suggestions!

Cheers,
Ovid

Replies are listed 'Best First'.
RE: (Ovid) Re: DBI Problem Solved
by Fastolfe (Vicar) on Sep 07, 2000 at 19:50 UTC
    Glad you got it working, though it seems strange that MS SQL Server would be reporting the truncation and not the DBI module...
      Just a note, the database will only report the error if it gets the SQL command. In this case, the ODBC driver never passes it along (what's the point if it fails the checks before going to be executed at the database?). And also, regardless of where the error occurs, DBI has a property to store all errors. $dbh->errstr or $DBI::errstr always holds the last error for the dbh or the last error that occurred.

      Most developers will bypass the need to physically print this by setting RaiseError => 1 when creating the dbh. It may be that MS SQL 7.0 was logging the error and Ovid didn't list that info.

      My own question to Ovid is why you chose to use ODBC. I'm not knocking its use, since I did the same thing, but I was curious if you tried FreeTDS, and if so, what errors came up.

      I had troubles with it and MS SQL 7.0 although people say it's possible, I've not seen it in my own experience, and no one has come up with any documentation that explicitly lines out what tweaks were necessary. It'd be nice if a user was so inclined to show us the light.

      Thanks if anyone takes this to task. ALL HAIL BRAK!!!