I\'m using DBI to query a SQLite3 database. What I have works, but it doesn\'t return the columns in order. Example:
Query: select col1, col2, col3, col4 from
Ideally you'd have a list of the columns you were SELECT'ing with DBI, and you'd use that array.
If you need to get the column names from the hash itself, this will work, and you can sort it, but there is no indication of the original SQL SELECT order (in the hash):
my %cols_hash = ("name" => "john", "age" => 2, "color" => "apalachian");
my $cols_hash_ref = \%cols;
my @keys = (sort keys %$cols_hash_ref);
my @vals;
foreach (@keys){ push @vals, $$cols_hash_ref{$_} };
Hope this helps.
$sth = $dbh->prepare($query) or die "Prepare exceptioin: $DBI::errstr!";
$rv = $sth->execute() or die "Execute exception: $DBI::errstr";
$res = $sth->fetchall_arrayref();
# Array reference with cols captions, which were retrived.
$col_names_array_ref = $sth->{NAME};
That should give you the column names in the original order, but I haven't tested it.
If you want to preserve the order, but still use a hash to refer to fields by name use:
$dbh->selectall_arrayref($sql,{ Slice => {} } );
This will give you an ordered array of hashes
You're asking for the result as a hash. A hash is inherently unordered. Perhaps you want fetchrow_arrayref
instead.
In fact, if you had looked at keys %$row
, you would have seen the corresponding keys being out of order as well. That's the nature of a hash... each key is paired with its value, but the overall ordering of keys or values is optimized for access, not external ordering.
Here's what I do:
use Data::Dump qw(dump);
# get column names in array
my @column_names_array= $sth->{NAME};
# print out column names in pretty format
print "Field names: \n";
dump(@column_names_array);
Replace the "what goes here" comment and the following loop with:
my $fields = join(',', @{ $result->{NAME_lc} });
print "$fields\n";
while (my $row = $result->fetchrow_arrayref) {
my $csv = join(',', @$row);
print "$csv\n";
}
NAME_lc
gives the field names in lowercase. You can also use NAME_uc
for uppercase, or NAME
for whatever case the database decides to return them in.
You should also probably be using Text::CSV or Text::CSV_XS instead of trying to roll your own CSV file, but that's another question.