Unexpected (?) try/catch Behavior

Discussion in 'Perl Misc' started by Rob Wilkerson, Nov 19, 2008.

  1. Disclaimer: I know enough Perl to get by when I absolutely have
    to use it, so maybe this is the correct behavior, but having never
    seen it in any other language, I thought I'd post the question to the
    group and maybe learn something.

    I have a scenario where I need to try to insert a record into a MySQL
    database and, if the insert fails due to, well, anything, then perform
    an update instead. To do this, I'm using the try/catch construct of
    the Error module:

    use Error qw:)try);

    try {
    $sql = qq {
    INSERT INTO table (
    field1,
    field2,
    field3,
    field4,
    field5
    )
    VALUES ( ?, ?, ?, ?, ? )
    };

    $sth = $mysql->prepare ( $sql );
    $sth->execute ( $value1, $value2, $value3, $value4, $value5 );
    $sth->finish();
    }
    catch Error with {
    $sql = qq {
    UPDATE table
    SET field1 = ?,
    field2 = ?,
    field3 = ?
    WHERE field4 = ?
    AND field5 = ?
    };
    $sth = $mysql->prepare ( $sql );
    $sth->execute ( $value1, $value2, $value3, $value4, $value5 );
    $sth->finish();
    };

    The code seems to be doing exactly what I expect. That is, dropping
    into the catch block and performing the update where a record exists,
    but the errors being caught are not being suppressed. I still get a
    lot of:

    DBD::mysql::st execute failed: Duplicate entry '121993-14196' for key
    1 at ./get_metrics.pl line 247.

    It's not the end of the world, but I'd prefer to suppress the message
    if there's a way to do that. Is this expected behavior? It certainly
    caught me by surprise and I spent a while trying to debug until I
    realized that if I looked past the messages, the work was getting
    done.

    I did try using the eval{} if ($@){} combo, but got the same result.

    Thanks.
     
    Rob Wilkerson, Nov 19, 2008
    #1
    1. Advertising

  2. Rob Wilkerson wrote:
    [...]
    > I have a scenario where I need to try to insert a record into a MySQL
    > database and, if the insert fails due to, well, anything, then perform
    > an update instead.

    [...]


    Not answering your Perl question, but
    what's wrong with:

    INSERT ... ON DUPLICATE KEY UPDATE



    Regards
    Dimitre
     
    Radoulov, Dimitre, Nov 19, 2008
    #2
    1. Advertising

  3. Rob Wilkerson <> writes:

    > The code seems to be doing exactly what I expect. That is, dropping
    > into the catch block and performing the update where a record exists,
    > but the errors being caught are not being suppressed. I still get a
    > lot of:
    >
    > DBD::mysql::st execute failed: Duplicate entry '121993-14196' for key
    > 1 at ./get_metrics.pl line 247.


    Being in a try block does not prevent DBI from printing error
    messages. You have to set the PrintError attribute on you database
    handle to 'off'.

    //Makholm
     
    Peter Makholm, Nov 19, 2008
    #3
  4. On Nov 19, 9:13 am, "Radoulov, Dimitre" <> wrote:
    > Rob Wilkerson wrote:
    >
    > Not answering your Perl question, but
    > what's wrong with:
    >
    > INSERT ... ON DUPLICATE KEY UPDATE
    >
    > Regards
    > Dimitre


    Hmmm. Nothing at all, except that I'd never needed it and wasn't aware
    of its existence. I'll definitely look at that since it'd be a much
    cleaner solution all the way around.

    Thanks for the clue.
     
    Rob Wilkerson, Nov 19, 2008
    #4
  5. On Nov 19, 9:41 am, Peter Makholm <> wrote:
    > Rob Wilkerson <> writes:
    > > The code seems to be doing exactly what I expect. That is, dropping
    > > into the catch block and performing the update where a record exists,
    > > but the errors being caught are not being suppressed. I still get a
    > > lot of:

    >
    > > DBD::mysql::st execute failed: Duplicate entry '121993-14196' for key
    > > 1 at ./get_metrics.pl line 247.

    >
    > Being in a try block does not prevent DBI from printing error
    > messages. You have to set the PrintError attribute on you database
    > handle to 'off'.


    Damn. I've built this thing to reuse a single database handle, so I
    can't really do that. I might want those errors somewhere else.

    Thanks for the insight.
     
    Rob Wilkerson, Nov 19, 2008
    #5
  6. Rob Wilkerson <> writes:

    > On Nov 19, 9:41 am, Peter Makholm <> wrote:
    >> Rob Wilkerson <> writes:
    >> > The code seems to be doing exactly what I expect. That is, dropping
    >> > into the catch block and performing the update where a record exists,
    >> > but the errors being caught are not being suppressed. I still get a
    >> > lot of:

    >>
    >> > DBD::mysql::st execute failed: Duplicate entry '121993-14196' for key
    >> > 1 at ./get_metrics.pl line 247.

    >>
    >> Being in a try block does not prevent DBI from printing error
    >> messages. You have to set the PrintError attribute on you database
    >> handle to 'off'.

    >
    > Damn. I've built this thing to reuse a single database handle, so I
    > can't really do that. I might want those errors somewhere else.
    >

    You can set the attribute anywhere you like. So you clear it to for
    just the try block alone, and set it back to one afterward.

    The other option is to clear PrintError and set RaiseError. That'll
    make your script die on DBI errors unless you wrap your DBI method
    calls in eval {} blocks. In case you want to continue on error, you
    can just print the error message yourself.

    I haven't used Error yet, so I don't know how it deals with DBI's
    RaiseError.

    Mart

    --
    "We will need a longer wall when the revolution comes."
    --- AJS, quoting an uncertain source.
     
    Mart van de Wege, Nov 19, 2008
    #6
  7. On Nov 19, 9:13 am, "Radoulov, Dimitre" <> wrote:
    > Rob Wilkerson wrote:
    >
    > [...]> I have a scenario where I need to try to insert a record into a MySQL
    > > database and, if the insert fails due to, well, anything, then perform
    > > an update instead.

    >
    > [...]
    >
    > Not answering your Perl question, but
    > what's wrong with:
    >
    > INSERT ... ON DUPLICATE KEY UPDATE


    So it turns out that I wasn't using this because it won't work (even
    though I only figured that out now). The table I'm inserting/updating
    has a dual primary key. That appears to be a no-no.
     
    Rob Wilkerson, Nov 19, 2008
    #7
  8. Rob Wilkerson

    Guest

    Rob Wilkerson <> wrote:
    > On Nov 19, 9:41=A0am, Peter Makholm <> wrote:
    > > Rob Wilkerson <> writes:


    First off, I don't agree with your tactic. If you get a duplicate key
    error, then by all means do an update instead if that is the logical thing
    to do. But if you get a "Server is currently on fire" error, I don't see
    that going on to try to update is the right thing to do.



    > > > The code seems to be doing exactly what I expect. That is, dropping
    > > > into the catch block and performing the update where a record exists,
    > > > but the errors being caught are not being suppressed. I still get a
    > > > lot of:

    > >
    > > > DBD::mysql::st execute failed: Duplicate entry '121993-14196' for key
    > > > 1 at ./get_metrics.pl line 247.

    > >
    > > Being in a try block does not prevent DBI from printing error
    > > messages. You have to set the PrintError attribute on you database
    > > handle to 'off'.

    >
    > Damn. I've built this thing to reuse a single database handle, so I
    > can't really do that. I might want those errors somewhere else.
    >
    > Thanks for the insight.


    Use local to localize the effect.

    {
    local $mysql->{PrintError}=0;
    ## do whatever. Errors will not be Printed
    };
    # at this point, PrintError has its original value.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Nov 19, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. bienwell
    Replies:
    4
    Views:
    3,856
    bienwell
    May 27, 2005
  2. John Salerno
    Replies:
    20
    Views:
    859
    John Salerno
    Aug 11, 2006
  3. oscartheduck
    Replies:
    7
    Views:
    5,349
    Steve Holden
    Apr 4, 2007
  4. Fabio Z Tessitore

    who is simpler? try/except/else or try/except

    Fabio Z Tessitore, Aug 12, 2007, in forum: Python
    Replies:
    5
    Views:
    378
  5. =?Utf-8?B?QUo=?=

    When to TRY and not to TRY

    =?Utf-8?B?QUo=?=, Oct 16, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    330
    sloan
    Oct 17, 2007
Loading...

Share This Page