Perl DBI::SQLite如何导出带列名的SQLite数据库表?
问题:为SQLite3表导出结果添加列名首行
我写了一个用于调试的Perl闭包,用来导出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');
解决方案
利用DBI语句句柄的{NAME}属性可以直接获取查询结果的列名列表,修改后的闭包代码如下:
sub something($) { my $dbh = shift; my $me = '_dump_tables'; my $sep = '-' x length($me); my $dump_table = sub ($) { # dump specified table or view my $table = shift; # 改用prepare/execute流程,以便获取列名 if (my $sth = $dbh->prepare("SELECT * FROM $table")) { $sth->execute; # 从语句句柄获取列名数组 my @columns = @{$sth->{NAME}}; my $rows = $sth->fetchall_arrayref; my $nsep = '-' x length($table); print "$me: $table\n"; print "${sep}--${nsep}\n"; # 先打印列名行 print join('|', @columns), "\n"; # 再打印数据行 foreach (@$rows) { print join('|', map { $_ // 'NULL' } @$_), "\n"; } } else { print "$me: Houston, we have a problem! ;-)\n"; } }; #... $dump_table->('EXAMPLE'); #... }
修改后输出示例
_dump_tables: EXAMPLE --------------------- ID|A|B 1|D1|K1 2|D2|K2 3|D3|K3 4|D4|K4 5|D5|K5 6|D6|K6
说明
- 无需额外查询SQLite系统表(如
pragma table_info),直接利用DBI原生属性获取列名,代码更简洁; - 该方法兼容所有DBI支持的数据库,不只限于SQLite;
- 保持了原代码的调试风格和输出格式,仅新增列名行。
内容的提问来源于stack exchange,提问作者U. Windl
相关产品推荐
相关产品推荐

