marc724 has asked for the wisdom of the Perl Monks concerning the following question:

I am retreiving mySql database record in a subroutine. I pass the subroutine an array reference " \@array" and the subroutine names the passed array "$arrayRef". I retreieve the data and store it as " $rowRef = $sth->fetchrow_arrayref". and store the returned record reference in the passed array " $arrayRef ->x = @$rowRef " When I look inside the $arrayRef (while debugging the subroutine) all is fine however, when i look for values at the program that calls the subroutine, no values are found. I'm new to perl and I think I'm not understanding a fundamental of data persistence after you finish the statement handle and disconnect the database. Any help would be greatly appreciated. Regards, Marc

Replies are listed 'Best First'.
Re: keep database records after select
by ikegami (Patriarch) on Mar 13, 2008 at 23:46 UTC

    Presumably you have

    @$arrayRef = (); while (my $row = $sth->fetch()) { push @$arrayRef, $row; }

    To quote from the docs for fetch_arrayref,

    Note that the same array reference is returned for each fetch, so don't store the reference and then use it after a later fetch. Also, the elements of the array are also reused for each row, so take care if you want to take a reference to an element. See also "bind_columns".

    Replace it with

    @$arrayRef = (); while (my $row = $sth->fetch()) { push @$arrayRef, [ @$row ]; # Make a copy. }

    or with

    @$arrayRef = @{ $dbh->selectall_arrayref($stmt_or_sth) };

    Updated to use OP's $arrayRef instead of a new variable.

Re: keep database records after select
by CountZero (Bishop) on Mar 13, 2008 at 23:57 UTC
    I think that besides the problem already mentioned by ikegami there is perhaps an additional error in your code since you have the correct data inside your subroutine, but none outside of it. The usual symptom of the problem indicated by ikegami is having lots of the same records in your data-structure.

    Perhaps you can show us some code to review?

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Thank you for responding and offering help. here's the code that doesn't work (in all of its ugliness.) and that is followed by what I think is just a cleaner version that DOES work??? I don't know why (could it be the SWITCH or the way I get the arguments to the subroutine???
      use Switch; use DBI; sub rec_exists; my (@retRows, @row, @tmp, $retRecs); while ($line = <>) { chomp($line); if ($line eq "q") { goto Exit; } else { $retRecs = rec_exists($line,\@retRows); } $tmp = @retRows[0]; @row = @$tmp; ($nKey, $fN, $lN, $bN, $hN, $mN) = @row; print "$nKey,$fN, $lN, $bN, $hN, $mN\n"; } Exit: exit(); sub rec_exists { my ($searchType,$searchParm,$retArrayRef) = split(/,/,@_[0]); my $dbh = DBI->connect("DBI:mysql:database=aaaaas;host=localhost", +"bbbbbb","cccccccccc",{'RaiseError' => 1}); my ($found, @row, @rows, $nKey, $sth); $rowRef; @rows = (); switch($searchType) { case "1" { # search using the nKey $nKey = $searchParm; chomp($nKey); $nKey =~ s/^\s+//; $nKey =~ s/\s+$//; $sth = $dbh->prepare("Select * from sContacts where nKey like + '$nKey%'"); $sth->execute(); $found = 0; while ( $rowRef = $sth->fetchrow_arrayref ){ $retArrayRef->[$found] = [ @$rowRef ]; $found++; } } } $sth->finish; $dbh->disconnect; return $found; }
      ====================== Now here's the stuff that does work
      use Switch; use DBI; my (@retRows,$retRecs, $searchKey); $searchKey = 'marcC'; $retRecs = test_exists($searchKey,\@retRows); print "returned $retRecs\n"; $tmp = @retRows[0]; print "@$tmp\n"; exit(); sub test_exists { my ($searchKey, $retRowsRef) = @_; my ($retArrayRef, $found); my $dbh = DBI->connect("DBI:mysql:database=aaaaa;host=localhost"," +bbbbbb","ccccccccc",{'RaiseError' => 1}); my $sth = $dbh->prepare("Select * from sContacts where nKey like +'$searchKey%'"); $sth->execute(); $found = 0; while ( $retArrayRef = $sth->fetchrow_arrayref ){ $retRowsRef->[$found] = [ @$retArrayRef ]; $found++; } $sth->finish; $dbh->disconnect; return $found; }