0

I have a Perl script which retrieves data from MySQL Database. this is the code:

sub startSession{
    my $self = shift;

    my $dsn = "dbi:".$self{platform}.":".$self{database}.":".$self{host}.":".$self{port};
    print "$dsn\n" ;
    $self{dbHandle} = DBI->connect($dsn,$user,$password);   
}

I have provided every information from an external file. I get the error message

DBI connect('dbname:**.**.**.**:3306','',...) failed: Access denied for user 'root'@'dbserver' (using password: NO) at line 89

Can't call method "prepare" on an undefined value at at line 97

I am very sure the root can connect from any host and the password is also correct.

  • 5
    One problem is that `$self{...}` has nothing to do with `my $self = shift`. You'd need to use `$self->{...}`. – cjm May 03 '12 at 18:30

3 Answers3

3

The key part of the warning that I see is "using password: NO". Check that the password is being set properly.

gpojd
  • 22,558
  • 8
  • 42
  • 71
  • How do I do that ? and one more thing, I dont even have a host named `'dbserver'` – user1304082 May 03 '12 at 18:22
  • 2
    If you turn on `use strict;` and `use warnings;` for this, I'd bet that it would give you more information on how to fix this than SO users. – gpojd May 03 '12 at 18:24
  • It gave me this warnings `Global symbol "$user" requires explicit package name at dbAdmin.pm line 27.` `Global symbol "$password" requires explicit package name at dbAdmin.pm line 27` – user1304082 May 03 '12 at 18:30
  • Somewhere in your script, you need to have `my $username = 'my_db_user';` and `my $password = 'my_db_password';`. – gpojd May 03 '12 at 18:41
  • I did that, the machine is a new clean installation, do you think i need to install any mysql drivers on it before i use this script ? – user1304082 May 03 '12 at 18:53
  • Are you not getting the "global symbol requires package name" anymore? Did you make the corrections that @cjm suggested, using $self-> to get the values out of whatever $self is referring to? – Barry May 03 '12 at 19:01
3

First, your immediate problem, is as @Sinan Ünür says, that you need to change $self{platform} to $self->{platform}, etc.

Your second immediate problem is that it appears you're getting $user and $password from nowhere (they are not passed to the function, so they are undefined unless they are global variables), which would explain the using password: NO part of the error. Maybe those should be $self->{user} and $self->{password}?

You should considering put this at the top of your module, at least during development, to automatically catch errors like these:

use warnings qw(all);
use strict;

But I'd also comment, that from a design perspective, you really ought to treat DSNs as opaque strings. Each database has its own DSN format. So if you ever want to target a different database, you'll need a different DSN format. Or, possibly, someday MySQL will use a different format (it already has two). Either way, it'll be much easier to change it one place, in a configuration file, than to track down each place you concatenate the various pieces together.

derobert
  • 49,731
  • 15
  • 94
  • 124
  • Like I have said in the problem statement, `user` and `password` are taken from an external file. – user1304082 May 03 '12 at 18:35
  • 1
    @user1304082: That's what you think anyway. It's quite evident that `$user` and `$password` aren't even declared in the scope you're using them, and that you need to provide more context if you want help solving your problem. – flesk May 03 '12 at 18:41
  • @user1304082 I have clarified my answer. You haven't passed $user and $password to the function (or, if you have, you're missing the `my $user = shift;`, `my $password = shift;` lines), so unless those are global variables, they're undefined. `use strict` will catch this. – derobert May 03 '12 at 18:44
2

Presumably, $self is a hashref, not a plain hash, and you don't have warnings on. So, turn them on, and use $self->{platform} etc.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
  • these are the warnings I get `Global symbol "$user" requires explicit package name at dbAdmin.pm line 27. Global symbol "$password" requires explicit package name at dbAdmin.pm line 27` – user1304082 May 03 '12 at 18:32
  • Quite right, but the OP's immediate problem is that the call to `DBI->connect` is failing. – pilcrow May 03 '12 at 18:37
  • 2
    Then clearly your variables $user and $password aren't getting set from the external file you mentioned. How are you doing that? – Barry May 03 '12 at 18:43