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

Hey guys I have a problem setting up a new webserver. Mysql 5.7 didnt work on Sierra so I am trying 5.6.

I have my webservice is up and running.
I have my mailservice is up and running.
I have my database set up and use Navicat to connect. All is fine.
Executing a perlscript on the website gives the following error:
[client 213.125.161.115:50545] AH01215: Can't call method "prepare" on + an undefined value at /Library/WebServer/CGI-Executables/bonriche/te +st.cgi line 57.: /Library/WebServer/CGI-Executables/bonriche/test.cgi
This is where the code is truing to connect to the database at: http://www.bonriche.com/cgi-bin/bonriche/test.cgi

Mysql is here: op/local/var/db/mysql56

System: MacOs Sierra 10.12.6

Perl:
perl5 @5.24.2_0+perl5_24 (active)
perl5.24 @5.24.2_0 (active)

p5-cgi @4.360.0_0 (active)
p5-dbd-mysql @4.43.0_0 (active)
p5-dbi @1.637.0_0 (active)

mysql56 @5.6.34_0 (active)
mysql56-server @5.6.34_0 (active)
mysql_select @0.1.2_3 (active)

I am lost, where do I fix this problem? Anyone?

KInd regards,

Ton

Replies are listed 'Best First'.
Re: DBD DBI Mysql Connect
by 1nickt (Canon) on Sep 10, 2017 at 20:07 UTC

    Hi, It sounds like you don't have a database handle defined. We can't really help unless you show the script.

    Please post it here in <code></code> tags. Please don't post more than about 30 lines of code. It should be a working example (See SSCCE). If your script is longer than that, make a new one with just the database connection part.

    Hope this helps!


    The way forward always starts with a minimal test.
      Hey there, thank you, here is a piece of code but I am sure this problem is in config somewhere. I have a few websites with working mysql and cgi running on my old Mac that I need to replace. This is only a snippet to test database connection while I am seeing up a new server on Sierra.
      use DBI; use Cwd; use CGI qw(:all); use LWP::Simple qw(get); use Net::SMTP; use Time::HiRes qw(gettimeofday); use File::Copy; $Cgi_Dir = qq(/Library/WebServer/CGI-Executables/bonriche); # MySql Database information $Db = qq(Platinum); $DbPort = qq(3306); $DbUserid = qq(root); $DbTable = qq(Classifieds); $DbUsers = qq(Users); $DbReceipts = qq(Receipts); $DbHost = qq(127.0.0.1); $DbPasswd = qq(******); $DbConnectionInfo = qq(DBI:mysql:database=$Db:$DbHost:$DbPort); # -------------------------------------------------------------------- +----------------------------------------- # # Query the database for the highest 'RegNum' and generate a new 'RegN +um' $Dbh = DBI->connect($DbConnectionInfo,$DbUserid,$DbPasswd); $Sth = $Dbh->prepare("SELECT RegNum FROM $DbUsers ORDER BY RegNum DESC + LIMIT 1"); $Sth->execute() or $Err_Num = "3002"; $Err_Mess = "$DBI::errstr": if ($Err_Num eq "0") { $ChkRegNum = ""; while (($ChkRegNum) = $Sth->fetchrow_array) { $LastRegNum = "$ChkRegNum"; } $Sth->finish(); $Dbh->disconnect; }

        die "Cannot connect: $DBI::errstr" unless ($Dbh);

        I really miss strict, warnings, taint mode, and RaiseError.

        Interpolating variables into SQL statements usually triggers my "use placeholders" warning (Re: Counting rows Sqlite, Re^2: Massive Memory Leak). But in the only SQL statement you show here, you "just" interpolate a constant table name into the SQL statement. Not as bad as variable data from the network, but still, you should use DBI's quote_identifier() method. That won't even break when you change $DbUsers.

        More:

        • You use string eq to compare numbers. Better use ==. How to remember that.
        • SELECT RegNum FROM Users ORDER BY RegNum DESC LIMIT 1 returns at most one value (LIMIT 1). That value is always the maximum value, due to ORDER BY RegNum DESC. Why don't you just SELECT MAX(RegNum) FROM Users? (MAX() in MySQL)
        • Plus, the code that you posted does not even compile:
          X:\>perl 1199050.pl syntax error at 1199050.pl line 26, near ""$DBI::errstr":" syntax error at 1199050.pl line 34, near "}" Execution of 1199050.pl aborted due to compilation errors. X:\>

          Better copy&paste from the actual source. Manual typing adds extra errors.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: DBD DBI Mysql Connect
by thanos1983 (Parson) on Sep 10, 2017 at 21:38 UTC

    Hello Umdurman,

    Similar question has been asked before Can't call method "prepare" on an undefined value.

    Most likely you are not connecting to your database. Enter a validation error on your connection, sample of untested code bellow:

    Change this:

    $Dbh = DBI->connect($DbConnectionInfo,$DbUserid,$DbPasswd);

    To this:

    my $dbh = DBI->connect($DbConnectionInfo,$DbUserid,$DbPasswd, { RaiseE +rror => 1 });

    From DBI documentation:

    $dbh = DBI->connect($dsn, $user, $password, { RaiseError => 1, AutoCommit => 0 });

    Update: I would also suggest to use error handling on your prepare statements also, if the connect to DB is good then the error is coming from the prepare statement.

    Sample of untested code:

    $Sth = $Dbh->prepare("SELECT RegNum FROM $DbUsers ORDER BY RegNum DESC + LIMIT 1") or die "Can't prepare: ", $dbh->errstr;

    Update 2: Very useful tutorial / tips and tricks with DBI Tricks with DBI.

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
      Thank you all guys, I found the solution. I run 2 domains on the testserver a .com and a .nl domain. The script was refering to the .com instead of the .nl My bad. Warm regards all, Ton

      I would also suggest to use error handling on your prepare statements also ...

      It's not necessary to use "or die" with statement handle calls (or any calls) if you've set RaiseError to true in the DBI connection string.


      The way forward always starts with a minimal test.
Re: DBD DBI Mysql Connect
by shmem (Chancellor) on Sep 10, 2017 at 21:12 UTC