Daedalus <[EMAIL PROTECTED]> wrote:
: 
: Hi all,
: 
: I have a cgi prog that complains about uninitialized
: values when I use the -w switch. To avoid those errors
: I have done stuff like this:
[snip]

    I think the best solution is a sub routine re-write.
I don't play with DBI much but I think bind-columns is
a poor choice for your fetch. (This is untested.)

sub address {
    my $query       =  CGI->new;

    my $searchid    =  $query->param( 'searchid' );
       $searchid    =~ s/\D//g;

    my $sql = qq{
        SELECT
            name,
            address1,
            address2,
            address3,
            address4
        FROM
            db.addresses
        WHERE
            id = $searchid
    };

    #
    # Assumes constants named
    #   CONNECT_STRING, USER, PASSWORD
    #   do exist
    #
    my $dbh = DBI->connect( CONNECT_STRING, USER, PASSWORD )
                    || die "Unable to connect: $DBI::errstr";

    my $sth = $dbh->prepare($sql) || die "Prepare failed: $dbh->errstr";

    $sth->execute() || die "Execute failed for data retrieval:
$dbh->errstr";

    my @address =  $sth->fetchrow_array
                    || die "A record was not found for that ID";

    my $address;
    foreach my $line ( @address ) {

        #
        # This sets the undefined values returned
        # by the query to ''
        #
        $line    ||= '';

        $address  .= "$line\n";
    }

    return $address;
}

    To get this to work in your program you would need
to call it as below. Having your sub routines return
values instead of performing output will aid you down
the road.

    print address(); # instead of get_address();


: # Up near the top with a bunch of other defs and the main prog...
: my @init_array = ("","","","","","","","","","");

    I wouldn't suggest using global variables.

: sub get_address
: {    my ($dbh, $sth, $searchid, $name, $address1, $address2, 
: $address3, $address4) = @init_array;

    Whenever you see variables followed by consecutive
numbers think: ARRAY. 


: 1. I am using the @init_array to avoid the
:    majority of uninitialization errors.
:    Is there a better way to do this?

    Rule of thumb: A subroutine shouldn't use
variables that were not passed to it. (There
are exceptions - like constants.) This is easier
to read and tells the next programmer what your
doing.

    my( $dbh, $sth, $searchid, @address ) = ('') x 8;

    But, $dbh, $sth, and $searchid are
initialized later and 'fetch_array' will
over-write any initialization of @address.


    Use 'my' to declare each variable the first
time a variable is used instead of at the
beginning of each code block. Try to maintain
the smallest scope possible. Don't litter your
file scoped variables with those used for
smaller scopes.
    In fact, try to eliminate file scoped
variables. Constants are available across the
file and other programmers expect that they
will be used throughout the program.

 
: 2. Is there a better to handle the re-init
:    of $address4? (DBD::Oracle must  return
:    UNDEF or some such for an empty address4
:    field.)

    I would recommend either 'map' or the example
above on all suspect fetches or finding a query
that returns undef as ''.

my $address .= "$_\n" foreach map $_ ||= '', @address;


: 3. Are both of these questions moot because
:    I should use -w  while developing the cgi,
:    but remove it before actual use?

    There is some debate whether removing
warnings is such a good thing. In a cgi program,
warnings go to the server logs and might
foretell a problem. I prefer using the module
to the command line switch. I leave warnings on
in production code as well as for testing. But
I'm not a full-time perl programmer. YMMV.


HTH,

Charles K. Clarkson
-- 
Head Bottle Washer,
Clarkson Energy Homes, Inc.
Mobile Home Specialists
254 968-8328





-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to