如何用 Perl 来展示数据库的表结构
有两个小工具是必不可少的,第一个就是导出数据用的脚本,这里命名为 emp。它能在本地主机上的 employees 数据库上执行任何的 SQL,并且把输出导出成为 tab 分隔的纯文本。
$ cat bin/emp
#!/bin/sh
perl -le 'use DBI; ($s=($d=DBI->connect(q(dbi:mysql:database=employees),q(emp),q()))->prepare_cached(join qq(),<STDIN>))->execute(@ARGV); $,=qq(\t); print STDERR @{$s->{NAME}}; print @r while @r=$s->fetchrow_array; $d->disconnect' $*
测试一下这个小工具:
$ echo 'select user()' | emp
user()
emp@localhost
注意,输出虽然有两行,但是第一行是标准出错(STDERR),是用来显示字段名的。真正的数据只有一行。
所以,可以这样来导出表结构:
$ echo 'desc employees' | emp > employees.desc
Field Type Null Key Default Extra
因为转向的只是标准输出,所以这里的字段名没有被转向到 employees.desc 文件中,而是直接显示在屏幕上了。
另外一个小工具是用来进行行转列的,这里把它先实现为一个 bash 函数。
$ row2col() { perl -MList::MoreUtils=each_arrayref -F\\t -lane 'END{ $ea=each_arrayref(@lines); print join qq(\t), @x while @x=$ea->()} push @lines, [@F]'; }
测试一下:
jjiang@flatpan:~$ echo -e '1\t2' | row2col
1
2
它工作了!
现在导出一行样本数据:
$ echo 'select * from employees limit 1' | emp | row2col
emp_no birth_date first_name last_name gender hire_date
10001
1953-09-02
Geogri
Facello
M
1986-06-26
而且这一列数据,恰好能够和刚才的表结构合并!所以,我们先把它存入文件 employees.data。
$ echo 'select * from employees limit 1' | emp | row2col > employees.data
emp_no birth_date first_name last_name gender hire_date
然后就是最后一个出场的小工具 merge-tab 了:
$ cat bin/merge-tab
#!/usr/bin/perl
use IO::File;
@f= map { IO::File->new($_) } @ARGV;
print $q,qq(\n) until ($q=join (qq(\t), map { m{(.*)} && $1 } map { $_->getline } @f))=~m{^\t+$}
这样,我们就可以做到需要的效果了:
$ merge-tab employees.desc employees.data
emp_no int(11) NO PRI 10001
birth_date date NO 1953-09-02
first_name varchar(14) YES Geogri
last_name varchar(16) YES Facello
gender enum('M','F') NO M
hire_date date NO 1986-06-26
没有评论:
发表评论