Deano
Deano

Reputation: 12220

perl script Use of uninitialized value error

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.

Upvotes: 1

Views: 303

Answers (1)

Borodin
Borodin

Reputation: 126752

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.

Upvotes: 3

Related Questions