Re: There's an error, but $sth->execute returns -1
[email protected] ("Martin J. Evans")
| Newsgroups | perl.dbi.users |
|---|---|
| Message-ID | <[email protected]> |
On 19/10/2010 18:03, Roode, Eric wrote:
> On Tuesday, October 19, 2010 3:59 AM, Martin J. Evans wrote:
>
>> All drivers I've tried this with report 2 things. The 23000 error
>> for the insert of a null into a column which does not allow nulls
>> (the tds_error packet) then a 01000 informational (tds_info) which
>> states the statement has been terminated.
>>
>> However, it does not get around the fact that SQLExecute is
>> returning SQL_SUCCESS_WITH_INFO with the broken driver. DBD::ODBC
>> uses the SQLExecute return to determine if the execute was
>> successful or not (as per the ODBC docs) and not the state of any
>> error it sees when recovering details of the errors and
>> informationals.
>>
>> I suppose this could be changed but it would need additional logic
>> everywhere "if (SQL_SUCCEEDED(ret))" is called and some way of
>> recording the states it has seen since the last ODBC call. I'm not
>> keen on doing that and not only because the driver in this case is
>> broken.
> I agree; it hardly seems worthwhile. This is what I put in place
> as a workaround. Does it look reasonable?
>
> $retval = $sth->execute(...);
> $sqlstate = $handle->state;
> if ( (!defined $retval)
> || (defined $sqlstate&& length $sqlstate
> && $sqlstate ne '00000'&& $sqlstate ne 'S1000'
> && substr($sqlstate,0,2) ne '01')
> )
> {
> ...handle error condition
>
>
> -- Eric
>
>
Yes.
I'd move that length test to later, just before the substr as it does
not matter until just before the substr. I think you might be mixing
ODBC 2 (e.g. the S1000) and 3 states - you should only get ODBC 3 states
via DBD::ODBC. I'd need to check that and I cannot easily right now.
I think you might be able to do this in a more straight forward way
using odbc_err_handler but I've not thought it through right now.
Martin