我正在编写一个使用DBI模块并连接到Sybase DB的Perl脚本。我正在调用一个存储过程(我无权访问该过程,因此无法发布示例代码),当我得到数据时,我得到一个错误消息:"error_handler: Data-conversion resulted in overflow“。我仍然得到了数据,并且在做了一些深入的研究之后,似乎列中的某些数据类型(如BigInt、nvarchar等)是罪魁祸首。现在的问题是,我如何解决这个问题?这可以在客户端修复吗?还是只能在服务器端修复?
my $dbh = DBI->connect("DBI:Sybase:server=$server", $username, $password, {PrintError => 0}) or die;
$dbh->do("use $database") or die;
my $sql = &getQuery;
my $sth = $dbh->prepare($sql) or die;
$sth->execute() or die;
while ($rowRef = $sth->fetchrow_arrayref) #Error seems to occur here
{
#Parse through each row
}解释该问题的FreeTDS 0.82日志的一部分:
_ct_bind_data(): column 7 is type 38 and has length 8
_ct_get_server_type(0)
_ct_get_client_type(type 38, user 0, size 8)
cs_convert(0x18dfed40, 0x7fff73216050, 0x18e44250, 0x7fff73215fa0, 0x18e387c0, 0x18e45a64)
_ct_get_server_type(30)
_ct_get_server_type(0)
converting type 127 (8 bytes) to type = 47 (9 bytes)
cs_convert() calling tds_convert
cs_convert() tds_convert returned 10
cs_prretcode(0)
cs_convert() returning CS_FAIL
cs_convert-result = 1发布于 2011-08-12 00:05:03
问题出在FreeTDS方面。我以前也遇到过同样的问题,并通过在select语句中将返回的字段转换为varchar成功地解决了这个问题。
由于您没有修改原始查询的权限,因此可以在代码中对返回的$sql变量执行正则表达式搜索和替换。具体地说,如果原始查询包含如下所示的部分
SELECT field1, field2, field3 FROM ...检索到查询语句后,可以运行
my $new_sql;
if ($sql =~ /SELECT\s+(.*)\s+FROM/i) { # match selected field string
my $field_str = $1;
my @fields = split ",", $field_str; # parse individual fields
map s/\s//g, @fields; # get rid of spaces
my $new_str = join ", ", (map {sprintf "convert(varchar, $_)"} @fields); # construct new query string
my $quoted_field_str = quotemeta($field_str); # prepare regex replacement string
$new_sql = $sql;
$new_sql =~ s/$quoted_field_str/$new_str/i # actual replacement
}
print $new_sql;当然,如果您的原始语句更复杂,您应该将其打印出来,并检查如何使用具有相同精神的通用替换来修改它。或者,您可以要求您的DBA (或有权访问存储过程的任何人)直接修改实际的查询。
希望这能有所帮助。
https://stackoverflow.com/questions/6602726
复制相似问题