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

I'm writing a website which uses a Postgresql database. I've never used Mason or DBI before, and I'm running into the following problem: DBD::Pg::st execute failed: ERROR:  Attribute 'sh' not found at /home/httpd/handler/obj/register.html line 122. Here's the code for the page; I'd trim it but I don't know where the error is coming from, and I'd rather error on the side of too *much* info. The error is referring, as far as I can tell, to the execution of the INSERT statement.
<!-- -*- mmm-classes: mason -*- --> % # Check to see if all of the required arguments arrived. % unless ($username and $password1 and $password2 and $email_address a +nd $birthdate) % { <Head><Title>Missing information</title></head> <Body> <H1>Missing information</h1> <P>Sorry, but your registration information could not be saved because it was missing the following:</p> <ul> % unless ($username) { <li> Username % } % unless ($password1) { <li> Password % } % unless ($password2) { <li> Password Verification % } % unless ($email_address) { <li> E-mail address % } </ul> <P>Please go <a href="register-form.html">back</a>, and fill in the missing information.</p> </body> % } elsif ($password1 != $password2) { <head> <title>Password Entries Do Not Match</title> </head> <body> <h1>Password Entries Do Not Match!</h1> <p>We're sorry, you must enter the same password in both fields. <P>Please go <a href="register-form.html">back</a>, and fill in the missing information.</p> </body> % } else { <%perl> # Let's see if this username is already taken $sql = "SELECT uid "; $sql .= "FROM Users "; $sql .= "WHERE user_name = ?"; $sth = $dbh->prepare($sql); $result = $sth->execute($username); my ($user_name_taken) = $sth->fetchrow_array; $sth->finish; <!- perl> % if ($user_name_taken) { <Head><Title>Username already taken</title></head> <Body> <H1>Username already taken </h1> $sth = $dbh->prepare($sql); $result = $sth->execute($username); my ($user_name_taken) = $sth->fetchrow_array; $sth->finish; <!- perl> % if ($user_name_taken) { <Head><Title>Username already taken</title></head> <Body> <H1>Username already taken </h1> <P>Sorry, but the username <b><% $username %></b> has already been taken by someone else. Please try to <a href="register-form.html">register</a> with a different username.</p> % } else { <%perl> # Since this username is unique, we can # store this user's information in the database $sql = "INSERT INTO users "; $sql .= " (user_name, user_password, user_birthdate, user_homepage, us +er_email)"; $sql .= " VALUES "; $sql .= " (?, ?, ?, ?, ?)"; $sth = $dbh->prepare($sql); $result = $sth->execute($username, $password1, $birthdate, $homepage, +$email_address); $sth->finish; <!- perl> % if ($result) { <%perl> $sql = "SELECT uid "; $sql .= "FROM Users "; $sql .= "WHERE user_name = ?"; $sth = $dbh->prepare($sql); $result = $sth->execute($username); my ($user_name_taken) = $sth->fetchrow_array; $sth->finish; <!- perl> % $session{user_id} = $user_id; <Head><Title>Registration inserted</title></head> <Body> <H1>Registration inserted</h1> <P>Your registration was successful.</p> <P>Welcome, <b><% $username %></b>!</p> % } else { <Head><Title>Error registering</title></head> <Body> <H1>Error registering</h1> <P>Sorry, but your registration was unsuccessful.</p> % } # Checking $result % } # Checking $user_name_taken % } # Ending top-level if/else <%once> my ($dbh, $sql, $sth, $result, $user_id); <!- once> <%init> $dbh = $m->comp("dbconnect.mcomp"); <!- init> <%args> $username => undef $password1 => undef $password2 => undef $email_address => undef $birthdate => undef $homepage => undef <!- args>

Replies are listed 'Best First'.
Re: DBD::Pg problems
by dstar (Scribe) on Aug 10, 2001 at 19:51 UTC
    Doink! The problem is that when the statement is executed, $password1 isn't being wrapped in '':
    dbd_st_execute: statement = >INSERT INTO users (user_name, user_passw +ord, user_birthdate, user_homepage, user_email) VALUES ('dstar', sh! +tupid!testpasswd, '11/14/1972', 'http://pele.cx/~dstar', 'dstar@pele. +cx')<

    Why is that happening, and how do I fix it?

      What's the data type of users.user_password in your database? Apparently DBD::prepare thinks it's not a char(n).

      Here's another possibility. This line: % } elsif ($password1 != $password2) {should probably be: % } elsif ($password1 ne $password2) {The numeric comparison makes me suspicious. Could it be causing DBD::execute to conclude that it doesn't need to be wrapped in quotes?

        That was it exactly. The worst part is, I looked at it last night and thought 'That isn't right'. Too much time awake, not enough coffee last night. Thanks.
Re: DBD::Pg problems
by VSarkiss (Monsignor) on Aug 10, 2001 at 19:49 UTC

    I've only recently started using Mason myself, so this may have nothing to do with your problem, but this syntax:

    <%perl> <!- perl>
    is brand new to me. I thought the correct syntax was:
    <%perl> </%perl>
    Similarly for your other <%init>, <%args>, etc. sections.

    As I said, I'm brand new to Mason, so this may be an alternative syntax I'm not aware of. Is it? (You may want to try the more "canonical" syntax and see if the error moves.)

    HTH

      That's new to me as well. Much of that code is cut-n-paste from the article on session handling referenced at masonhq; I hadn't even noticed it.
      It turns out to have been the numeric compare of the password variables, though.