如何使用 Perl 中的 DBI 按顺序获取列名和行数据?

发布于 2024-08-22 02:53:05 字数 1758 浏览 6 评论 0原文

我正在使用 DBI 查询 SQLite3 数据库。我所拥有的有效,但它不会按顺序返回列。示例:

Query:  select col1, col2, col3, col4 from some_view;
Output:

    col3, col2, col1, col4
    3, 2, 1, 4
    3, 2, 1, 4
    3, 2, 1, 4
    3, 2, 1, 4
    ...

(values and columns are just for illustration)

我知道发生这种情况是因为我使用了哈希,但是如果我只使用数组,我该如何取回列名称?我想要做的就是为任何任意查询得到这样的结果:(

    col1, col2, col3, col4
    1, 2, 3, 4
    1, 2, 3, 4
    1, 2, 3, 4
    1, 2, 3, 4
    ...

也就是说,我需要输出以正确的顺序和列名。)

我是一个 Perl 新手,但我真的认为这将是一个简单的问题。 (我之前已经在 Ruby 和 PHP 中完成过此操作,但在 Perl 文档中查找我要查找的内容时遇到了麻烦。)

这是我目前拥有的内容的精简版本:

use Data::Dumper;
use DBI;

my $database_path = '~/path/to/db.sqlite3';

$database = DBI->connect(
  "dbi:SQLite:dbname=$database_path",
  "",
  "",
  {
    RaiseError => 1,
    AutoCommit => 0,
  }
) or die "Couldn't connect to database: " . DBI->errstr;

my $result = $database->prepare('select col1, col2, col3, col4 from some_view;')
    or die "Couldn't prepare query: " . $database->errstr;

$result->execute
    or die "Couldn't execute query: " . $result->errstr;

########################################################################################### 
# What goes here to print the fields that I requested in the query?
# It can be totally arbitrary or '*' -- "col1, col2, col3, col4" is just for illustration.
# I would expect it to be called something like $result->fields
########################################################################################### 

while (my $row = $result->fetchrow_hashref) {
    my $csv = join(',', values %$row);
    print "$csv\n";
}

$result->finish;

$database->disconnect;

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 some_view;
Output:

    col3, col2, col1, col4
    3, 2, 1, 4
    3, 2, 1, 4
    3, 2, 1, 4
    3, 2, 1, 4
    ...

(values and columns are just for illustration)

I know this is happening because I'm using a hash, but how else do I get the column names back if I only use an array? All I want to do is get something like this for any arbitrary query:

    col1, col2, col3, col4
    1, 2, 3, 4
    1, 2, 3, 4
    1, 2, 3, 4
    1, 2, 3, 4
    ...

(That is, I need the output is in the right order and with the column names.)

I'm very much a Perl novice, but I really thought this would be a simple problem. (I've done this before in Ruby and PHP, but I'm having trouble tracking down what I'm looking for in the Perl documentation.)

Here's a pared down version of what I have at the moment:

use Data::Dumper;
use DBI;

my $database_path = '~/path/to/db.sqlite3';

$database = DBI->connect(
  "dbi:SQLite:dbname=$database_path",
  "",
  "",
  {
    RaiseError => 1,
    AutoCommit => 0,
  }
) or die "Couldn't connect to database: " . DBI->errstr;

my $result = $database->prepare('select col1, col2, col3, col4 from some_view;')
    or die "Couldn't prepare query: " . $database->errstr;

$result->execute
    or die "Couldn't execute query: " . $result->errstr;

########################################################################################### 
# What goes here to print the fields that I requested in the query?
# It can be totally arbitrary or '*' -- "col1, col2, col3, col4" is just for illustration.
# I would expect it to be called something like $result->fields
########################################################################################### 

while (my $row = $result->fetchrow_hashref) {
    my $csv = join(',', values %$row);
    print "$csv\n";
}

$result->finish;

$database->disconnect;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

鸠书 2024-08-29 02:53:05

将“此处内容”注释和以下循环替换为:

my $fields = join(',', @{ $result->{NAME_lc} });
print "$fields\n";

while (my $row = $result->fetchrow_arrayref) {
    my $csv = join(',', @$row);
    print "$csv\n";
}

NAME_lc 给出小写的字段名称。您还可以使用 NAME_uc 表示大写,或使用 NAME 表示数据库决定返回它们的任何情况。

您可能还应该使用 Text::CSVText::CSV_XS 而不是尝试滚动您自己的 CSV 文件,但这是另一个问题。

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.

强者自强 2024-08-29 02:53:05

如果您想保留顺序,但仍然使用散列按名称引用字段,请使用:

$dbh->selectall_arrayref($sql,{ Slice => {} } );

这将为您提供一个有序的散列数组

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

烏雲後面有陽光 2024-08-29 02:53:05

在 SELECT 之前在 ARRAY 中定义列名

理想情况下,您将拥有一个使用 DBI SELECT'ing 的列的列表,并且可以使用该数组。

如果您需要从哈希本身获取列名,这将起作用,并且您可以对其进行排序,但没有指示原始 SQL SELECT 顺序(在哈希中):

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{$_} };  

希望这有帮助。

当我搜索时,我找到了一种从 DBI 获取列名的方法:

$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};          

这应该以原始顺序为您提供列名,但我还没有测试过。

Define your column names in an ARRAY before your SELECT

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.

When I searched I found a way to get the column names from the DBI:

$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.

为你拒绝所有暧昧 2024-08-29 02:53:05

这就是我所做的:

    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);

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);
凉风有信 2024-08-29 02:53:05

您要求结果作为哈希值。哈希本质上是无序的。也许您需要fetchrow_arrayref

事实上,如果您查看过keys %$row,您也会发现相应的键也乱序了。这就是哈希的本质……每个键都与其值配对,但键或值的整体排序针对访问进行了优化,而不是外部排序。

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.

GRAY°灰色天空 2024-08-29 02:53:05
#!/usr/bin/perl                                                                                                                                                                        
use strict;
use warnings;
use DBI;
my $database = "your_mysqldb";
my $username = "your_dbusername";
my $password = "your_dbpassword";
my $tblename = "your_mysqldbtable";
my $dsn = "DBI:mysql:embedded";
#                                                                                                                                                                                      
my %attr = ( PrintError=>0,   #turn off error reporting via warn()                                                                                                                     
             RaiseError=>1);  #turn on error reporting via die()                                                                                                                       
my $dbh = DBI->connect($dsn,$username,$password,\%attr);
print "Connected to the MySQL database $database for username $username\n";
my $sql = "DESCRIBE ".$tblename;
my $sth = $dbh->prepare($sql);  
$sth->execute();   #execute the prepared query                                                                                                                                         
my @heads;
my $i=0;
while(my $r = $sth->fetchrow_arrayref()){
    $heads[$i]=$r->[0];
    $i++;
}
my $j=0;
foreach(@heads){
    print "$j $_\n";
    $j++;
}
$sth->finish();
$dbh->disconnect(); #disconnect from mysql db   
#!/usr/bin/perl                                                                                                                                                                        
use strict;
use warnings;
use DBI;
my $database = "your_mysqldb";
my $username = "your_dbusername";
my $password = "your_dbpassword";
my $tblename = "your_mysqldbtable";
my $dsn = "DBI:mysql:embedded";
#                                                                                                                                                                                      
my %attr = ( PrintError=>0,   #turn off error reporting via warn()                                                                                                                     
             RaiseError=>1);  #turn on error reporting via die()                                                                                                                       
my $dbh = DBI->connect($dsn,$username,$password,\%attr);
print "Connected to the MySQL database $database for username $username\n";
my $sql = "DESCRIBE ".$tblename;
my $sth = $dbh->prepare($sql);  
$sth->execute();   #execute the prepared query                                                                                                                                         
my @heads;
my $i=0;
while(my $r = $sth->fetchrow_arrayref()){
    $heads[$i]=$r->[0];
    $i++;
}
my $j=0;
foreach(@heads){
    print "$j $_\n";
    $j++;
}
$sth->finish();
$dbh->disconnect(); #disconnect from mysql db   
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文