in reply to Re: DBI not erroring out on Insert
in thread DBI not erroring out on Insert

I would include an "or die" clause on the connect() like I did below because you are not guaranteed to have the 'RaiseError' in effect unless the connect succeeds.

Read the source code of DBI's connect method. It will use Carp to croak when RaiseError is in effect if the connection failed.


Improve your skills with Modern Perl: the free book.

Replies are listed 'Best First'.
Re^3: DBI not erroring out on Insert
by Marshall (Canon) on Sep 14, 2011 at 00:38 UTC
    We are way off the original topic now... I did look at the DBI source code as chromatic suggested... I guess this is the sort of thing where everybody can claim "victory" depending upon their point of view!

    The code in DBI's connect() related to RaiseError:

    unless ( $attr->{HandleError} && $attr->{HandleError}->($msg, $drh, $dbh)) { Carp::croak($msg) if $attr->{RaiseError}; Carp::carp ($msg) if $attr->{PrintError}; }
    Ok, fair enough. If RaiseError is true, then the DBI croaks on an error.

    I was pondering a different question. I was wondering what happens if connect() fails because the arguments supplied are are of wrong number or type - in a more general case, what happens if the arg list is such that the DBI connect cannot recognize that RaiseError is intended to be 'on'? That case is handled by this DBI code:

    Carp::croak('Usage: $class->connect([$dsn [,$user [,$passwd [,\%attr]] +]])') if (ref $old_driver or ($attr and not ref $attr) or ref $pass);
    So I guess a more accurate description of what the DBI does: The DBI will croak no matter what the state of RaiseError if it detects an invalid argument list to connect(). I also found out through testing that if you misspell "Raiseerror", the DBI also croaks - it will croak for any syntax error that is detected (the spec doesn't say this, but the code does it).

    I'm testing right now with SQLite which doesn't have users or passwords so there are scenarios with MySQL that I am unable to test.

    At the end of the day, if I omit the "or die" clause to a connect (which also specifies the RaiseError attribute), then I would have to be 100% sure that the "or die" code can never be executed under any circumstance. I can't prove that and that is certainly not part of the public specification.

    Now I know that the "hey Mom, Jimmy's mom let's him to X" (the other guys do it defense) is pretty weak, but I learned my "bad" habit about this from Programming the Perl DBI" by Alligator Descartes and Tim Bunce.

    I think that I am on very solid ground with my current practice and recommendations.

    Back to original question in the original post!!!
    I still have not found any way at all for a prepare of the INSERT statement to succeed where one of the columns does not exist in the table.

      Do you think what you found out about connect/RaiseError that is not documented is worth adding to the DBI pod? I've not seen a discussion on what is raised by DBI during connect if RaiseError is set or not before. I have a commit bit on DBI if you have any suggestions.

        No. I do not think that this is worth a comment in the DBI pod.

        For folks who want to know some super details, I say "go for it!". The DBI code is actually so complex that I cannot say that x or y or even z is completely true.

        The DBI code is written in such a way that it does "work as advertised". Yes, we can talk about details, but I think that it would be a huge mistake to change things without careful consideration.

        So, having said that, I would be happy to work on the DBI.