假设我正在查询表格,如下所示:
$dbh->selectrow_hashref('SELECT id,name FROM foos WHERE name = "bar"');
当然,id将是一个整数,但生成的hashref将在内部存储一个值作为Perl PV而不是IV.反过来,当将数据序列化为例如JSON时,这将产生不希望的结果.
当然,可以在值上手动调用0,但有没有办法让DBI自动将其存储为实际整数而不仅仅是一个看起来像数字的字符串?同时也承认DBIx :: Class和朋友有解决这个问题的方法,但DBI的寂寞呢?
解决方法
根据您的数据库驱动程序,您可以*在
bind_col
中使用类型提示:
use DBI qw(:sql_types); ... my $sth = $dbh->prepare('SELECT id,name FROM foos WHERE name = "bar"'); $sth->execute; $sth->bind_col(1,undef,{ TYPE => sql_INTEGER,StrictlyTyped => 1,DiscardString => 1 }); while (my $hr = $sth->fetchrow_hashref) { say to_json $hr; }
这会尝试将第一列(从一个索引编译)绑定到sql_INTEGER类型,如果转换为任何值失败,则会引发错误.作为bohica notes,DiscardString属性是必要的,因为它“抛弃了数据的字符串部分(pv).”
*根据DBI文档:
Few drivers support specifying a data type via a
bind_col
call (most will simply ignore the data type).
根据this thread(虽然我无法验证它),DBD :: Oracle和DBD :: ODBC支持它,DBD :: Pg可能支持它,而DBD :: MysqL则不支持它.我不确定其他车手.