perl - DBI::Sybase 数据转换导致溢出

标签 perl sybase dbi freetds

我正在编写一个使用 DBI 模块并连接到 Sybase 数据库的 Perl 脚本。我正在调用一个存储过程(一个我无权访问的存储过程,因此我无法发布示例代码),当我取回数据时,我收到一条错误消息,内容为“error_handler:数据转换导致溢出”。我仍然取回数据,经过深入研究后,似乎列中的某些数据类型(例如 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

最佳答案

问题出在 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(或任何有权访问存储过程的人)直接修改实际查询。

希望这对您有所帮助。

关于perl - DBI::Sybase 数据转换导致溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6602726/

相关文章:

Perl DBI 语句句柄和错误处理

perl - 使用 SOAP::Lite 服务 stub

mysql - Perl dbi prepare 引用错误

perl - 事件 perl 从 @ARGV 中删除 "^"

java - 日志数据库连接挂起

java - 为什么 Sybase 不使用功能索引?

sql - 启用 sqsh -m bcp 选项获取列名?

ruby - 在哪里放置 ruby​​ .gem 文件以便 Shoes.setup 可以找到它们?

java - Perl 和 Java 中的多重继承是否相同?

perl - 如何从 Perl 中的哈希中删除键?