开发者

Perl referencing and deferencing hash values when passing to subroutine?

I've been banging my head over this issue for about 5 hours now, I'm really frustrated and need some assistance.

I'm writing a Perl script that pulls jobs out of a MySQL table and then preforms various database admin tasks. The current task is "creating databases". The script successfully creates the database(s), but when I got to generating the config file for PHP developers it blows up.

I believe it is an issue with referencing and dereferencing variables, but I'm not quite sure what exactly is happening. I think after this function call, something happens to $$result{'databaseName'}. This is how I get result: $result = $select->fetchrow_hashref()

Here is my function call, and the function implementation:

Function call (line 127):

generateConfig($$result{'databaseName'}, $newPassword, "php");

Function implementation:

sub generateConfig {
    my($inName) = $_[0];
    my($inPass) = $_[1];
    my($inExt)  = $_[2];

    my($goodData) = 1;
    my($select)   = $dbh->prepare("SELECT id FROM $dat开发者_C百科abasesTableName WHERE name = '$inName'");
    my($path)     = $documentRoot.$inName."_config.".$inExt;
    $select->execute();

    if ($select->rows < 1 ) {
            $goodData = 0;
    }

    while ( $result = $select->fetchrow_hashref() )
    {
            my($insert) = $dbh->do("INSERT INTO $configTableName(databaseId, username, password, path)".
                                   "VALUES('$$result{'id'}', '$inName', '$inPass', '$path')");

    }

    return 1;
    }

Errors:

Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 142.
Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 154.

Line 142:

        $update = $dbh->do("UPDATE ${tablename}
                        SET ${jobStatus}='${newStatus}' 
                        WHERE id = '$$result{'id'}'");

Line 154:

 print "Successfully created $$result{'databaseName'}\n";

The reason I think the problem comes from the function call is because if I comment out the function call, everything works great!

If anyone could help me understand what's going on, that would be great.

Thanks,

p.s. If you notice a security issue with the whole storing passwords as plain text in a database, that's going to be addressed after this is working correctly. =P

Dylan


You do not want to store a reference to the $result returned from fetchrow_hashref, as each subsequent call will overwrite that reference.

That's ok, you're not using the reference when you are calling generate_config, as you are passing data in by value.

Are you using the same $result variable in generate_config and in the calling function? You should be using your own 'my $result' in generate_config.

      while ( my $result = $select->fetchrow_hashref() )
      #       ^^  #add my

That's all that can be said with the current snippets of code you've included.

Some cleanup:

  1. When calling generate_config you are passing by value, not by reference. This is fine.
  2. you are getting an undef warning, this means you are running with 'use strict;'. Good!
  3. create lexical $result within the function, via my.
  4. While $$hashr{key} is valid code, $hashr->{key} is preferred.
  5. you're using dbh->prepare, might as well use placeholders.

    sub generateConfig {
      my($inName, inPass, $inExt) = @_;
    
      my $goodData = 1;
      my $select   = $dbh->prepare("SELECT id FROM $databasesTableName WHERE name = ?");
      my $insert   = $dbh->prepare("
                        INSERT INTO $configTableName(
                          databaseID
                          ,username
                          ,password
                        ,path) 
                        VALUES( ?, ?, ?, ?)" );
      my $path     = $documentRoot . $inName . "_config." . $inExt;
      $select->execute( $inName );
    
      if ($select->rows < 1 ) {
            $goodData = 0;
      }
    
      while ( my $result = $select->fetchrow_hashref() )
      {
        insert->execute( $result->{id}, $inName, $inPass, $path );
      }
    
     return 1;
    

    }


EDIT: after reading your comment

I think that both errors have to do with your using $$result. If $result is the return value of fetchrow_hashref, like in:

$result = $select->fetchrow_hashref()

then the correct way to refer to its values should be:

 print "Successfully created " . $result{'databaseName'} . "\n";

and:

    $update = $dbh->do("UPDATE ${tablename}
                    SET ${jobStatus}='${newStatus}' 
                    WHERE id = '$result{'id'}'");

OLD ANSWER:

In function generateConfig, you can pass a reference in using this syntax:

generateConfig(\$result{'databaseName'},$newPassword, "php");

($$ is used to dereference a reference to a string; \ gives you a reference to the object it is applied to).

Then, in the print statement itself, I would try:

 print "Successfully created $result->{'databaseName'}->{columnName}\n";

indeed, fetchrow_hashref returns a hash (not a string).

This should fix one problem.

Furthermore, you are using the variable named $dbh but you don't show where it is set. Is it a global variable so that you can use it in generateConfig? Has it been initialized when generateConfig is executed?


This was driving me crazy when I was running hetchrow_hashref from Oracle result set. Turened out the column names are always returned in upper case. So once I started referencing the colum in upper case, problem went away: insert->execute( $result->{ID}, $inName, $inPass, $path );

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜