in reply to dbi 500 error

If you're getting a 500 error, this tells me you are running this through a Web server. You're not sending any output back to the client, so your error log is probably complaining about "Premature end of script headers". That doesn't mean your program is wrong, just that you either need to run it from the command line or convert it to a proper CGI program. However, I wouldn't have a CGI program issuing "CREATE TABLE" commands :)

Assuming your shebang line is correct, here's a simple, complete CGI program:

#!/usr/local/bin/perl -wT use strict; use CGI qw/:standard/ print header, start_html( -title => 'Test program' ), h1( 'Hello world' ), end_html;

Update: Ack! I see a problem in your program:

my $table = $dbh->prepare qq' CREATE TABLE players (realname CHAR(20), = gold CHAR(40))');

Take a close look at your single quotes! It looks like you missed a parentheses.

my $table = $dbh->prepare( qq' CREATE TABLE players (realname CHAR(20), gold CHAR(40))');

Further, I'm already seeing some database design issues that you need to think about. Include a non-identifying ID for the player. If you use the realname as the ID, you can't easily update it.

create table players ( player_id INTEGER NOT NULL, firstname VARCHAR(15), lastlast VARCHAR(20), gold INTEGER );

Now, have every table that needs to link to the players table use the player_id. You can then change the other data at will.

Cheers,
Ovid

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Replies are listed 'Best First'.
Re: (Ovid) Re: dbi 500 error
by Anonymous Monk on Jan 23, 2003 at 05:29 UTC
    I'm kinda new at Perl myself (being reformed from days as an amatuer Java geek). Chromatic (an old college friend) refered me to perlmonks. I have moved to a new server and am consitently getting 500 errors trying to run simple scripts (even hellocgi.cgi that comes with Apache bundled with Indigo Perl). I can execute the scripts fine, locally, using Apache, but on my server they consistently throw 500 errors. File permissions are set to 775, and the shebang is all good. I can't get it to work, but Ovid said something that made me want to ask a question:

    Ovid wrote:
    You're not sending any output back to the client, so your error log is probably complaining about "Premature end of script headers". That doesn't mean your program is wrong, just that you either need to run it from the command line or convert it to a proper CGI program.

    The program works from the command line (obviously, PuTTY won't render the HTML). And it works locally. The phrase "convert it to a proper CGI program" caught my attention, though. In Java everything got compiled into classes. I can't imagine needing to do that to a Perl script. What did you mean by the statement?

    Thanks,
    Mike

      Hi Mike,

      Note: this code is untested.

      What did you mean by [convert it to a proper CGI program]?

      That's a straightforward question, but regrettably, the answer is not as clear. Typically, when working with in a CGI environment, several issues arise that may not occur in different environment. You have to worry about sending headers, formatting your output correctly, maintaining state, etc. In other words, consider what happens if you want a simple "hello, world" program:

      perl -le 'print "Hello, world!"'

      And if I want to personalize this:

      perl -e 'print "Hello, ", shift' Ovid

      Now, what happens if I want to convert that to a CGI program? The first example is easy, but I won't do it as a one-liner because that's not going to work with a Web server.

      print "Content-Type: text/plain; charset=ISO-8859-1\n\nHello, world"';

      That's roughly equivalent to the "Hello, world" program, but what do we do if we want to personalize it? We'll switch to CGI.pm to make our life easier. First, we assume the following form:

      <form action="/cgi-bin/test.cgi"> <input type="text" name="name"> <input type="submit" name="submit" value="Press me!"> </form>

      Then we read it and respond:

      #!/usr/bin/perl -T use warnings; use strict; use CGI qw(:standard); my $_name = param('name') || ''; my ($name) = $_name =~ /([[:alnum:][:space:][:punct:]]+)/; $name ||= 'Anonymous Monk'; print header, <<"END_HTML"; <html> <head><title>Greeting Page</title></head> <body><p>Hello, $name</body> </html> END_HTML

      And if we need persistence:

      #!/usr/bin/perl -T use warnings; use strict; use CGI qw(:standard); my $_name = cookie('name') || param('name') || ''; my ($name) = $_name =~ /([[:alnum:][:space:][:punct:]]+)/; $name ||= 'Anonymous Monk'; my $cookie = cookie( -name => 'name', -value => $name ); print header(-cookie => $cookie), <<"END_HTML"; <html> <head><title>Greeting Page</title></head> <body><p>Hello, $name</body> </html> END_HTML

      I could go on further, but I think you get the basic idea. The last listing is where I got to from a simple command line "hello, world" script to a CGI program. If you see some strange things in the last script, note my .sig line which has a link to my CGI course. That should answer many questions. In any event, I hope this answered your question.

      Cheers,
      Ovid

      New address of my CGI Course.
      Silence is Evil (feel free to copy and distribute widely - note copyright text)

Re: (Ovid) Re: dbi 500 error
by Anonymous Monk on Jan 18, 2002 at 03:08 UTC
    I have taken your advice into consideration and have come up with my new version(that does not create and errors).
    #!/usr/local/bin/perl use CGI qw/:standard/; use DBI; print header, start_html( -title => 'Test ' ), h1( 'Hello world' ), end_html; my $dbh; $dbh = DBI->Connect("DBI:mysql:strossus:localhost","strossus","******* +*"); my $table = $dbh->prepare (qq' CREATE TABLE players (firstname CHAR(20), lasttname CHAR(20), email CHAR(50), player INTEGER NOT NULL,, hitp INTEGER, maxhtipp INTEGER, minatt INTEGER, maxatt INTEGER, exp INTEGER, gold INTEGER)'); $table->execute(); $talbe->finish(); $dbh->disconnect();

    Edited 2002-01-17 by Ovid to hide password :(

      I just edited your post to hide your password. Be careful!

      First, like I said, I still wouldn't want to run a CREATE TABLE command through a CGI script. What happens when someone calls your program again? It will try to create a table that already exists. I've never tried to do that, so I can't guess what will happen. I suspect that things will die a horrible death, but no guarantees.

      Second, you should either check all of your DBI calls for success, or add the RaiseError attribute to your connect call. See trs80's response below.

      Last, you'll still want to have a unique, non-indentifying ID for the table.

      CREATE TABLE players ( player_id INTEGER NOT NULL PRIMARY KEY, firstname VARCHAR (20) NOT NULL, lastname VARCHAR (20) NULL, ... more stuff here ... ) CREATE TABLE foo ( foo_id INTEGER NOT NULL PRIMARY KEY, player_id INTEGER NOT NULL REFERENCES players (player_id), stuff VARCHAR(30) NOT NULL )

      Learning databases is a good thing, but be sure to learn them well. It's very easy to do thing wrong. Life is Hell for the programmer who is forced to work with a poorly designed database.

      Update: I just tossed in the other table to show you how things things work. If your database will be simple enough that you only need one table, it's not necessary. If, however, it's going to be complex, you'll want to start learning these design issues.

      Cheers,
      Ovid

      Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

        i am confused about why i would need the second table