我有一些代码需要确保在插入数据库之前某些数据在mysql枚举中.我发现这样做最干净的方法是以下代码:
sub enum_values { my ( $self, $schema, $table, $column ) = @_; # don't eval to let the error bubble up my $columns = $schema->storage->dbh->selectrow_hashref( "SHOW COLUMNS FROM `$table` like ?", {}, $column ); unless ($columns) { X::Internal::Database::UnknownColumn->throw( column => $column, table => $table, ); } my $type = $columns->{Type} or X::Panic->throw( details => "Could not determine type for $table.$column", ); unless ( $type =~ /\Aenum\((.*)\)\z/ ) { X::Internal::Database::IncorrectTypeForColumn->throw( type_wanted => 'enum', type_found => $type, ); } $type = $1; require Text::CSV_XS; my $csv = Text::CSV_XS->new; $csv->parse($type) or X::Panic->throw( details => "Could not parse enum CSV data: ".$csv->error_input, ); return map { /\A'(.*)'\z/; $1 }$csv->fields; }
我们正在使用DBIx :: Class.当然有更好的方法来实现这个目标吗?(请注意,$ table变量来自我们的代码,而不是来自任何外部源.因此,没有安全问题).
不需要那么英勇.使用相当现代版本的DBD :: mysql,DBI的列信息方法返回的哈希包含密钥中有效枚举值的预拆分版本mysql_values
:
my $sth = $dbh->column_info(undef, undef, 'mytable', '%'); foreach my $col_info ($sth->fetchrow_hashref) { if($col_info->{'TYPE_NAME'} eq 'ENUM') { # The mysql_values key contains a reference to an array of valid enum values print "Valid enum values for $col_info->{'COLUMN_NAME'}: ", join(', ', @{$col_info->{'mysql_values'}}), "\n"; } ... }