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

Hi, I need help with this script. I have 2 tables in the database, Registrations, and Alerts. People signup to get email alerts from our site and their email address is stuff ed into the Alerts table. This script takes the bad email addresses (that bounce) and the script deletes the emails from the alerts and registrations table. My problem is that we store the email addresses in a single field separated by ~~~ (3 tildas) in the alerts database. The script works but after it runs we sometimes end up with emails in a single string that are NOT separated by the ~~~. In looking at the script, it looks correct to me. Can someone find where I'm going wrong?
#!/usr/bin/perl print "Content-type: text/html\n\n"; ######## REQUIRED FILES ########### require "cgi-lib.pl" || die "Error loading cgi-lib.pl"; require "db-common.sub" || die "Error loading db-common.sub"; $alertstable = "alerts"; $regtable = "registrations"; &Conn_to_DB; ###### Connect to bad emails database and get all the emails $SQL = "Select * from bademails ORDER BY ID DESC"; &Do_SQL; while ($pointer = $sth->fetchrow_hashref) { $bademail = $pointer->{'email'}; ###### Connect to alerts database and get the entries that match t +he bademail list $SQL2 = "Select * from $alertstable where email LIKE '%$bademail%' +"; &Do_SQL2; while ($pointer2 = $sth2->fetchrow_hashref) { $item = $pointer2->{'jobtype'}; $alerttype = $pointer2->{'alerttype'}; $emaillist = $pointer2->{'email'}; $ID = $pointer2->{'ID'}; @emails = split /~~~/,$emaillist; @goodemails = (); foreach $address (@emails) { #print "$ID, $address<Br>\n"; if ($address ne $bademail) { push @goodemails,$address; } } #end foreach $newlist=join('~~~',@goodemails); $SQL3 = "UPDATE $alertstable SET email='$newlist' WHERE jobtype='$i +tem' and alerttype='$alerttype'"; &Do_SQL3; print "updated $ID, $elist<Br>\n"; } #end while ($pointer2 = $sth2->fetchrow_hashref) { ###### Connect to reg database and set the alerts to nothing if it + matches a bademail $SQL3 = "UPDATE $regtable SET alerts='$alerts' WHERE email='$badem +ail'"; &Do_SQL3; print "Reset Reg. ID: $ID, $bademail<Br>\n"; } # end while $dbh->disconnect; exit;

Replies are listed 'Best First'.
Re: Help with script
by ww (Archbishop) on May 17, 2006 at 21:11 UTC
    These are NOT direct answers but may be of some help:
    • Unless you have a very specific and well-thought-out reason for using cgi-lib.pl, which is largely obsolete and widely deprecated, use CGI::pm >fixing typo/brain spasm: CGI.pm instead.
    • Your words and code seem to disagree with each other: I see not 2 tables, but 3: bademails, alerts, and registrations. Am I missing something?
    • &Conn_to_DB; Undefined subroutine &main::Conn_to_DB ...
      (As usual, using strict and warn would have let you know about that mistake)
Re: Help with script
by GrandFather (Saint) on May 17, 2006 at 21:12 UTC

    "Sometimes" problems almost always depend either on things we don't know about the data, or result from issues that strictures will pick up for you.

    For a start add use strict; use warnings; to your code then fix up all the errors that that shows up. If you still have problems trim the code down so it either doesn't use a database, but shows the problem, or use the trick shown in I know what I mean. Why don't you? to include enough of a database to demonstrate the problem in your sample code.

    While you are generating the next itteration of the sample code remember to trim out all the extranious cruft. If the problem isn't in the CGI stuff, omit the CGI stuff. We can't try your code if it depends on stuff we don't have (including data we don't have).


    DWIM is Perl's answer to Gödel
Re: Help with script
by TeraMarv (Beadle) on May 18, 2006 at 05:57 UTC
    I don't know if this is going to help you much but you are breaking relational database rules.

    By storing more than one e-mail address in a single field you are making life difficult for yourself. This is screaming out for one row per e-mail address.

    An 'E-mail' table that contains an address field and a status field along with your foreign key fields will make it so much easier to maintain.