Date: Sun, 01 Jul 2001 07:24:08 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: how to dynamic append row in table  with perl CGI module?
Message-Id: <3B3F0858.D5F190A2@earthlink.net>

jackkon wrote:
> 
> hi all:
> I want to read data from access and put it into the table by cgi.
> I use the CGI module.
> Now, I can read the data correctly.
> But I fail to put the data to the table by cgi.
> My code is below.
> It is the only one method that I can think(I am a newer in cgi).
> Dose any better method to make the mission?
> Thanks for your help.
> ============================================================================
> ==

use strict;
use warnings;

> use CGI;
use CGI::Carp qw(fatalsToBrowser);

> use Win32::ODBC;
> my $cgi=new CGI;

Since only one CGI object is ever used, you'd be better off removing
this line, and removing "$cgi->" from all the places it's used.

> print $cgi->header;
> print $cgi->start_html;

print header, start_html;

> my $DSN='myaccess';
> my $TABLE='cust';
> if(!($dbm=new Win32::ODBC($DSN))){
>  print "Reason: " . Win32::ODBC::Error(). "\n";
>  exit;
> }

1) You ought to declare $dbm, 2) you should avoid indirect syntax, even
when it's just a call to new, and 3) the syntax you're using isn't
perlish.

my $dbm = Win32::ODBC->new $DSN
  or die "Reason: ". Win32::ODBC::Error(). "\n";

> my @data=undef;
> my @title=undef;

This populates each of @data and @title with a one element array, the
value of that element being undef.  Ie, it's as if you'd done:
my @data = (undef);
my @title = (undef);
What you really want is for them to be empty arrays -- which you can
accomplish by not assigning anything to them.
my (@data, @title);

> if(! $dbm->Sql("SELECT * FROM $TABLE")){

Are you sure that what you want is "if(!" ?  If this is indeed what you
want, it would probably look better as:
if( $dbm->Sql("SELECT * FROM $TABLE") == 0 ) {

Actually, since you most likely want the program to exit if this call
fails, this is probably not what you want... consider something like:

$dbm->Sql("SELECT * FROM $TABLE") == 0 or die "$^E\n"

>  @title=$dbm->fieldnames();
>  while($dbm->fetchrow()){
>   my %row_hash=$dbm->DataHash();
>   my @row_array=values %row_hash;
>   push(@data, \@row_array);
>  }

What makes you think that values %row_hash will be in any particular
order?  It will be the same order as keys %row_hash would be, but you
never check that... What you probably want here is
  @title = $dbm->fieldnames;
  push @data, \@{$dbm->DataHash}{@title} while( $dbm->fetchrow );
  

> }


> my $MYTABLE=undef;
> $MYTABLE.='
> print $cgi->table(
>  {-border=>2},
>  $cgi->caption({-align=>top}, "FROM DATABASE",),
>  $cgi->Tr(
>   {-align=>center, -valign=>top},
>   [
>   $cgi->th(\@title),';
> for($i=0; $i<=$#data; $i++){
>  $MYTABLE.='$cgi->td('.$data[$i].'),';
> }
> $MYTABLE.='
>   ],
>  ),
> );';
> eval ($MYTABLE);       ## not work

eval is evil.  What's wrong with doing this in a normal way?

print table {-border->2},
	caption( {-align=>top}, "From Database" ),
	Tr( {-align=>center, -valign=>top}, [
		th( \@table ),
		map { td $_ } @data,
	] );

> print $cgi->end_html;

-- 
The longer a man is wrong, the surer he is that he's right.


