如何使用 Perl 中的 DBI 按顺序获取列名和行数据?
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
将“此处内容”注释和以下循环替换为:
NAME_lc
给出小写的字段名称。您还可以使用NAME_uc
表示大写,或使用NAME
表示数据库决定返回它们的任何情况。您可能还应该使用 Text::CSV 或 Text::CSV_XS 而不是尝试滚动您自己的 CSV 文件,但这是另一个问题。
Replace the "what goes here" comment and the following loop with:
NAME_lc
gives the field names in lowercase. You can also useNAME_uc
for uppercase, orNAME
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.
如果您想保留顺序,但仍然使用散列按名称引用字段,请使用:
这将为您提供一个有序的散列数组
If you want to preserve the order, but still use a hash to refer to fields by name use:
This will give you an ordered array of hashes
在 SELECT 之前在 ARRAY 中定义列名
理想情况下,您将拥有一个使用 DBI SELECT'ing 的列的列表,并且可以使用该数组。
如果您需要从哈希本身获取列名,这将起作用,并且您可以对其进行排序,但没有指示原始 SQL SELECT 顺序(在哈希中):
希望这有帮助。
当我搜索时,我找到了一种从 DBI 获取列名的方法:
这应该以原始顺序为您提供列名,但我还没有测试过。
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):
Hope this helps.
When I searched I found a way to get the column names from the DBI:
That should give you the column names in the original order, but I haven't tested it.
这就是我所做的:
Here's what I do:
您要求结果作为哈希值。哈希本质上是无序的。也许您需要
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.