使用Perl来展示数据库的表结构

发布时间:2019-08-31编辑:脚本学堂
导出数据用的脚本,这里命名为 emp。它能在本地主机上的 employees 数据库上执行任何的 SQL,并且把输出导出成为 tab 分隔的纯文本。

本文介绍的内容需要用到两个小工具。
一、导出数据用的脚本,这里命名为 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 -Ft -lane 'END{ $ea=each_arrayref(@lines); print join qq(t), @x while @x=$ea->()} push @lines, [@F]'; }

测试一下:
jjiang@flatpan:~$ echo -e '1t2' | 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