【发布时间】:2013-02-01 14:23:02
【问题描述】:
我正在尝试编写 Perl 代码,该代码接受 SQL INSERT 语句的绑定,并识别可能导致 INSERT 因错误数据而被拒绝的问题,并修复它们。为此,我需要获取并解释列元数据。
$dbh->column_info 方法以编码形式返回信息。我仔细阅读了官方 CPAN 文档,但仍然感到困惑。
my $sth_column_info
= $dbh->column_info( $catalog, $schema, $table, undef );
my $columns_aoh_ref = $sth_column_info->fetchall_arrayref(
{ COLUMN_NAME => 1,
DATA_TYPE => 1,
NULLABLE => 1,
ORDINAL_POSITION => 1,
COLUMN_DEF => 1,
}
);
say $table;
for my $href (@$columns_aoh_ref) {
my @list;
while ( my ( $k, $v ) = each %$href ) {
push @list, "$k=" . ( $v // 'undef' );
}
say join '|', @list;
}
输出是:
dw_phone
NULLABLE=0|COLUMN_DEF=undef|DATA_TYPE=4|ORDINAL_POSITION=1|COLUMN_NAME=phone_id
NULLABLE=0|COLUMN_DEF=undef|DATA_TYPE=4|ORDINAL_POSITION=2|COLUMN_NAME=phone_no
NULLABLE=1|COLUMN_DEF=undef|DATA_TYPE=4|ORDINAL_POSITION=3|COLUMN_NAME=phone_ext
NULLABLE=0|COLUMN_DEF=undef|DATA_TYPE=1|ORDINAL_POSITION=4|COLUMN_NAME=phone_type
NULLABLE=0|COLUMN_DEF=undef|DATA_TYPE=1|ORDINAL_POSITION=5|COLUMN_NAME=phone_location
NULLABLE=1|COLUMN_DEF=undef|DATA_TYPE=1|ORDINAL_POSITION=6|COLUMN_NAME=phone_status
NULLABLE=0|COLUMN_DEF=undef|DATA_TYPE=11|ORDINAL_POSITION=7|COLUMN_NAME=insert_date
NULLABLE=0|COLUMN_DEF=undef|DATA_TYPE=11|ORDINAL_POSITION=8|COLUMN_NAME=update_date
例如,在哪里可以找到数据类型代码到字符串的映射?我应该使用 DATA_TYPE、TYPE_NAME 还是 SQL_DATA_TYPE?我应该使用 NULLABLE 还是 IS_NULLABLE,为什么这两种口味?
我可以理解记录(更不用说实现)数据库通用接口的难度。但我想知道是否有人知道使用特定于 MySQL 的 DBI 的参考手册?
更新 1:
试图通过使用 array 而不是哈希来检索 all 信息来揭示更多信息:
my $sth_column_info
= $dbh->column_info( $catalog, $schema, $table, undef );
my $aoa_ref = $sth_column_info->fetchall_arrayref; # <- chg. to arrayref, no parms
say $table;
for my $aref (@$aoa_ref) {
my @list = map $_ // 'undef', @$aref;
say join '|', @list;
}
现在我可以看到很多潜在有用的信息混在其中。
dw_contact_source
undef|dwcust1|dw_contact_source|contact_id|4|BIGINT|20|undef|undef|10|0|undef|undef|4|undef|undef|1|NO|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|1|bigint(20)|undef|0
undef|dwcust1|dw_contact_source|company_id|4|SMALLINT|6|undef|undef|10|0|undef|undef|4|undef|undef|2|NO|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|1|smallint(6)|undef|0
undef|dwcust1|dw_contact_source|contact_type_id|4|TINYINT|4|undef|undef|10|0|undef|undef|4|undef|undef|3|NO|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef||tinyint(4)|undef|0
undef|dwcust1|dw_contact_source|insert_date|11|DATETIME|19|undef|0|undef|0|undef|undef|9|-79|undef|4|NO|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef||datetime|undef|0
undef|dwcust1|dw_contact_source|update_date|11|DATETIME|19|undef|0|undef|0|undef|undef|9|-79|undef|5|NO|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef|undef||datetime|undef|0
所以我的问题是:
- 如何获取这些元数据的相应名称/描述?
- 我如何
fetchall_arrayref使用符号而不是整数来满足我的需求? (我试过fetchall_arrayref([qw/COLUMN_NAME DATA_TYPE/])并找回了所有undefs;现在我只是在猜测。)
更新 2:
现在我在 DBD::mysql.pm 中挖掘,发现了一个非常有趣的数组:
my @names = qw(
TABLE_CAT TABLE_SCHEM TABLE_NAME COLUMN_NAME
DATA_TYPE TYPE_NAME COLUMN_SIZE BUFFER_LENGTH DECIMAL_DIGITS
NUM_PREC_RADIX NULLABLE REMARKS COLUMN_DEF
SQL_DATA_TYPE SQL_DATETIME_SUB CHAR_OCTET_LENGTH
ORDINAL_POSITION IS_NULLABLE CHAR_SET_CAT
CHAR_SET_SCHEM CHAR_SET_NAME COLLATION_CAT COLLATION_SCHEM COLLATION_NAME
UDT_CAT UDT_SCHEM UDT_NAME DOMAIN_CAT DOMAIN_SCHEM DOMAIN_NAME
SCOPE_CAT SCOPE_SCHEM SCOPE_NAME MAX_CARDINALITY
DTD_IDENTIFIER IS_SELF_REF
mysql_is_pri_key mysql_type_name mysql_values
mysql_is_auto_increment
);
这些与 fetchall_arrayref 返回的内容完全对应。现在我可以看到我有 四个 选择来学习数据类型,所以让我们看看是否有任何代码被记录在案。
更新 3:
DBI Recipes 是关于将信息检索回 Perl 的 CPAN DBI 文档的一个非常好的附件(尤其是 {select|fetch}{row|all}_{hash|array} 方法。)
【问题讨论】:
-
metacpan.org/module/DBD::mysql 可能是一个不错的起点。
-
谢谢——如果我没看错的话,语句句柄部分与我最相关。但该技术似乎要求您首先在桌子上执行
SELECT *。 (还没有检查它是否适用于空表。)对整个表使用column_info方法似乎是更好的方法,这就是为什么我更愿意学习如何使用它。跨度>