in reply to DBI output in 3 columns

try this:

#!/usr/bin/perl -w use CGI; use DBI; use strict; use vars qw($dbh); BEGIN { $dbh = DBI->connect("DBI:ODBC:PM_Pages","","", { RaiseError => 1 }); } END { $dbh->disconnect if $dbh; } my $q; $q = new CGI; print $q->header, $q->start_html("District List"), $/; my $sql = "select District, DIST from Districts"; my $sth = $dbh->prepare($sql); $sth->execute(); my $cols = 3; my @rows = @{$sth->fetchall_arrayref}; # my $col_length = POSIX::ceil(@rows / $cols); my $col_length = (@rows - @rows % -$cols) / $cols; print "<table>", $/; for my $row (0 .. $col_length - 1) { print "<tr>", $/; for my $col (0 .. $cols - 1) { my $idx = $row + ($col * $col_length); last unless $idx < @rows; printf '<td><a href="%d">%s</a></td>', @{$rows[$idx]}[1,0]; print $/; } print "</tr>", $/; } print "</table>", $/; print $q->end_html, $/;

notice that you need to know the total number of rows and that you need to be able to have indexed access to the result set in order to build the table by directly iterating through the cells in column-major, row-minor order. this is why all the data is fetched into an array before display.

you specify that your table always has 600 rows, so you may be able to do this without an array, if you can get indexed (i.e. non-sequential) access to your result set. i doubt this is possible through ODBC (it probably requires a DB-specific driver and DB support for non-sequential cursors).

update: substituted working code for broken code