类似于如何获取Sqlite3数据库上的列名列表?,但仍然不同:
出于调试目的,我编写了一个转储 SQLite3 表的闭包。 输出不是很漂亮,但它有效:
sub something($)
{
my $dbh = shift;
my $me = '_dump_tables';
my $sep = '-' x length($me);
my $dump_table = sub ($) { # dump specified table or view
if (defined(my $rows = $dbh->selectall_arrayref(
"SELECT * FROM $_[0]"))) {
my $nsep = '-' x length($_[0]);
print "$me: $_[0]\n";
print "${sep}--${nsep}\n";
foreach (@$rows) {
print join('|', map { $_ // 'NULL' } @$_), "\n";
}
} else {
print "$me: Houston, we have a problem! ;-)\n";
}
};
#...
$dump_table->('table_name');
#...
}
输出可能如下所示:
_dump_tables: EXAMPLE
---------------------
1|D1|K1
2|D2|K2
3|D3|K3
4|D4|K4
5|D5|K5
6|D6|K6
我想将列名称添加为第一行,寻找一个最好简单的解决方案。
EXAMPLE
表可以被认为是:
CREATE TABLE EXAMPLE (
ID INTEGER PRIMARY KEY NOT NULL
A VARCHAR(128) NOT NULL,
B VARCHAR(128) NOT NULL
);
INSERT INTO EXAMPLE (A, B)
VALUES ('D1', 'K1'), ('D2', 'K2'), ('D3', 'K3'),
('D4', 'K4'), ('D5', 'K5'), ('D6', 'K6');
注意:由于某种原因,即使
ID
没有 AUTOINCREMENT
,这也是有效的。
可以使用
NAME
方法,但是需要将 selectall
拆分为 prepare
、execute
和 fetchall
才能有语句句柄来调用它:
my $select = $dbh->prepare("SELECT * FROM $_[0]");
$select->execute;
if (defined(my $rows = $select->fetchall_arrayref)) {
my $nsep = '-' x length($_[0]);
print "$me: $_[0]\n";
print "${sep}--${nsep}\n";
my $header = $select->{NAME};
foreach ($header, @$rows) {
print join('|', map { $_ // 'NULL' } @$_), "\n";
}
或者直接在数据库上使用
column_info
方法。这不太通用,因为它仅适用于 SELECT *
。
my $dump_table = sub ($) { # dump specified table or view
if (defined(my $rows = $dbh->selectall_arrayref(
"SELECT * FROM $_[0]"))) {
my @colnames;
my $info = $dbh->column_info(undef, undef, $_[0], '%');
while (my $col = $info->fetchrow_arrayref) {
# COLUMN_NAME is at index 3 (4th field)
unshift @colnames, $col->[3];
}
my $nsep = '-' x length($_[0]);
print "$me: $_[0]\n";
print "${sep}--${nsep}\n";
foreach (\@colnames, @$rows) {
print join('|', map { $_ // 'NULL' } @$_), "\n";
}