1

I have this perl script that alters MySQL database data, everytime I run it I get the following error

 Use of uninitialized value in addition (+) at ./cdr_db.pl-m line 88.

Looking at the code from line 80 to 88

### archive cdr records
    $sth = $dbh2->prepare(
        "SELECT max($tablename2_archive.EventID) from $tablename2_archive")
      or die "Couldn't prepare statement: " . $dbh->errstr;
    $sth->execute()
      or die
"Database error trying to poll $tablename2_archive.EventID for archive use: "
      . $sth->errstr . "\n";
    my $nextEventID = $sth->fetchrow_array + 1;

here is the full script

http://pastebin.com/4hmaS3b9

I just don't get what the error is.

4
  • It looks as though $sth->fetchrow_array is undef. Use Data::Dumper to take a closer look at $sth and $sth->fetchrow_array. Try printing out the query (after the variables are filled in) and see if there are any problems with it. Commented Jul 8, 2013 at 14:05
  • Also, you should be aware that since $sth->fetchrow_array is an array, you're calling it in a scalar context when you add 1 to it... Commented Jul 8, 2013 at 14:14
  • @JackManey: Despite its identifier fetchrow_array returns a list, which is a very different thing from an array. Commented Jul 8, 2013 at 14:55
  • @Borodin - [checks docs] Right you are. My apologies, I usually use fetchrow_arrayref or fetch with bound parameters. Commented Jul 8, 2013 at 15:21

1 Answer 1

3

fetchrow_array returns a list of values, which is empty if there are no more rows to be fetched.

Adding one to a list is bad Perl style, but it has the effect of using the last element of the list, which is what you want here since there should be only a single return value.

As it stands, fetchrow_array could be returning either an empty list or a list ending with undef. Both would evaluate as undef in the addition. The first is most likely, and I guess you are trying to add a record to an empty table, when there is no previous EventID column?

You should write

$sth->execute;
my @row = $sth->fetchrow_array;
die "No results returned" unless @row;
my $nextEventID = $row[0] + 1;

or it would be much nicer (and faster, for what it's worth) to bind the column you are fetching

my $eventID;

$sth->execute;
$sth->bind_columns(\$eventID);
$sth->fetch;
die "No results returned" unless defined $eventID;
my $nextEventID = $eventID + 1;

But you will still have to check whether $eventID is undef before you do the arithmetic.

Lastly. Sorry this is so long-winded, you should make the EventID column NOT NULL so that you can be sure a value of undef indicates that no rows have been found, and you should make use of the MySQL AUTO_INCREMENT column property so that you don't have to calculate the IDs yourself. The declaration would look like

EventID INT NOT NULL AUTO_INCREMENT

and you would just omit a value for that column when you write your INSERT INTO.

I hope this helps.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.