4

我想像 .schema 一样检索 sqlite 数据库模式信息,但使用 Perl DBI。第一次尝试是检索表名,$dbh->tables但我获得了重复的表名。它们是表本身的一个条目和我拥有的每个索引的一个条目(table_a 有 3 个索引,b 有一个)这背后的基本原理是什么?

DB<7> x $dbh->tables;
0  '"main"."table_a"'
1  '"main"."table_a"'
2  '"main"."table_a"'
3  '"main"."table_b"'
4  '"main"."sqlite_master"'
5  '"temp"."sqlite_temp_master"'
6  '"main"."table_a"'
7  '"main"."table_b"'

我很感激有人可以为这三个相关问题提供提示:如何仅获取表(不执行 uniq)以及为什么每个索引只有一行?如何获取索引信息?总而言之,如何获得.schema的等效信息?

[更新] 我在 DBI 1.627 看到过

@names = $dbh->tables;        # deprecated

但它没有提到原因。

他们建议使用

@names = $dbh->tables( $catalog, $schema, $table, $type );

但是在阅读了解释此参数的 DBI table_info 之后,我还没有完全理解如何填充它们以获取表的信息以仅获取表名一次,或者如果有可能获得所有表名,相同的信息使用 .schema。

任何示例或更详细用法的链接将不胜感激。

[[UPDATE]]
仅供将来参考,这些是阻止我在此处提问之前自己找到答案的两个问题:

1- 谷歌将我​​引导到一个非常古老的 DBD-sqlite 文档页面,其中几乎没有任何内容,我没有注意页面顶部的最新版本的链接。

2- 在问这里之前,我在其他线程中阅读了有关 table_info (正确答案)的信息,但是几年没有编写 DBI 代码,我陷入了新手陷阱之一。由于 $dbh->tables 返回一个数组,我没有注意 table_info 返回一个语句处理程序,所以当x $dbh->table_info(...)在调试器中尝试并获得一个空哈希时,我被卡住了。我忘记了将 fetch 部分调用到返回的 $sth 的需要。

4

2 回答 2

3

如何只获取表格(不做 uniq)

$dbh->tables我猜这个接口太简单了,无法代表 SQL 引擎和各种驱动程序的复杂性。正如您所注意到的,您应该table_info()改用。

特别是,请参阅DBD::SQLite 文档table_info()(在撰写本文时为 v1.39),因为 DBD 文档可以告诉您 db 和驱动程序支持哪些功能(例如,SQLite 没有目录)。像这样的东西会给你你想要的:

use feature qw(say);
...

# Get info on every ('%') TABLE entity in the "main" schema.  Catalog is blank
# b/c DBD::SQLite and/or SQLite itself has no concept of catalogs.
my $sth = $dbh->table_info('', 'main', '%', 'TABLE');

while (my $r = $sth->fetchrow_hashref) {   # outputs:  table_a
  say $r->{TABLE_NAME};                    #           table_b
}

为什么每个索引都有一行?

不确定,但可能是tables()简单界面的意外。同样,用于table_info()枚举表格和类似表格的对象。

如何获取索引信息?

可能支持实验statistics_info()方法。

总而言之,如何获得.schema的等效信息?

你很幸运。DBD::SQLite 驱动程序提供了一个table_info扩展字段'sqlite_sql',对我来说,它在每个表后面给出了“CREATE TABLE ...”语句。(也是我从 .schema 中得到的。)尝试:

my $sth = $dbh->table_info('', 'main', '%', 'TABLE');

while (my $r = $sth->fetchrow_hashref) {
  say $r->{sqlite_sql};
}
于 2013-07-15T15:57:40.897 回答
0

如何列出表名:

my $sth=$dbh->table_info('','main','%', 'TABLE')
my $tables = [map{$_->[2]} @{$sth->fetchall_arrayref()}];
say join("\n", @$tables);
于 2013-07-16T21:01:41.040 回答