【问题标题】:select count(*) not working with perl DBI选择计数(*)不适用于 perl DBI
【发布时间】:2013-03-25 07:53:13
【问题描述】:

我的代码的目标是根据一个特定参数返回表中行数的计数。

这是有效的代码:

######### SQL Commands
### Connect to the SQL Database
my $dbh = DBI->connect($data_source, $user, $pass)
    or die "Can't connect to $data_source: $DBI::errstr";

### Prepare the SQL statement and execute
my $sth1 = $dbh->selectrow_array("select count(*) from TableInfo where Type = '2'")
or die "Can't connect to $data_source: $DBI::errstr";

### Disconnect from Database statements are completed.
$dbh->disconnect;
######### end SQL Commands 


print $sth1;

这将成功打印一个数字,在本例中为 189。 当我尝试使用相同的代码但更改“Type = '2'”(应返回值 2000)时,我收到以下错误:

DBD::ODBC::db selectrow_array failed: [Microsoft][ODBC Driver 11 for SQL Server]Numeric value out of range (SQL-22003) at ./getTotalExpSRP.cgi line 33, <DATA> line 225.
Can't connect to dbi:ODBC:BLTSS_SRP: [Microsoft][ODBC Driver 11 for SQL Server]Numeric value out of range (SQL-22003) at ./getTotalExpSRP.cgi line 33, <DATA> line 225.

我到处搜索,但找不到发生这种情况的原因。 从问题的症状来看,我猜想返回的结果的大小是有限制的,但我找不到任何支持证据。

我已在我的 Microsoft SQL 2005 服务器上运行跟踪,并且可以确认 sql 语句正在正常运行且没有错误。

我查看了我的 odbc 跟踪日志,但不幸的是,在将工作示例与失败示例进行比较时,我无法得出任何有用的信息。

任何帮助将不胜感激!

谢谢,

【问题讨论】:

    标签: sql perl odbc dbi


    【解决方案1】:

    现在我们已经看到了我可以解释的痕迹。 DBD::ODBC 调用 SQLDescribeCol 并被告知:

    DescribeCol column = 1, name = , namelen = 0, type = unknown(0), 精度/列大小 = 10, scale = 0, nullable = 1 显示尺寸 = 11

    然后它调用 SQLColAttribute 并被告知列大小为 4。由于列类型未知(我不确定驱动程序为什么这样做) DBD::ODBC 决定将列绑定为 char(4) 和所以一旦计数大于 3 位,它就会溢出。

    这里使用的 DBI 和 DBD::ODBC 版本确实很旧,我怀疑最新版本会更好地处理这个问题。

    【讨论】:

    • 这就是答案。升级模块后,我不再收到任何错误。另外值得注意的是,我不需要使用 bind_col
    【解决方案2】:

    Numeric value out of range 是类型转换错误。 TYPE 应该是一个字符/字符串的数字吗?如果应该是数字,请使用数字

    my $sth1 = $dbh->selectrow_array(
        "select count(*) from TableInfo where Type=2")  # Type=2, not Type='2'
    

    或使用占位符,让 Perl 和数据库驱动程序担心类型转换

    my $sth = $dbh->prepare("select count(*) from TableInfo where Type=?");
    $sth->execute(2);
    $sth->execute('2');     # same thing
    my $st1 = $sth->fetchall_arrayref;
    

    【讨论】:

    • 尝试这种方法会给我同样的错误信息。我不认为这是 SQL 语句的问题。它似乎无法处理来自 SQL 的响应。我对此的唯一证明是,当 Type = 2 时,我获得了成功的数据。只有当 Type = 1 时才会失败。数据的差异是 189 与 2000 的大小 - 希望这能提供一些见解。
    • 另一个证明它可能不是 SQL 语句的证据是,如果我使用我的 $sth = $dbh->prepare("select count(*) from TableInfo where Type=?"); $sth->执行(1); $sth->完成;没有错误。只有当我在执行命令后尝试操纵响应时才会出现错误。
    • 你有什么版本的 perl DBI? perl -MDBI -le '打印 $DBI::VERSION'。如果它是最近的,那么 DBD::ODBC 设置/导出 DBI_TRACE=DBD=x.log 并再次运行它,然后从故障前的 x.log 中发布行。对于 Windows,您可能需要在该版本代码中使用不同的引号。
    • 我正在运行 DBI 1.52 版。我运行 export DBI_TRACE=DBD=/var/log/DBI.log 然后运行脚本,但 DBI.log 文件中没有打印任何内容。我做错了什么?
    • 问题是未返回 count(*) 的列类型 - 请参阅“type = unknown(0)”,因此 DBD::ODBC 回退到 SQLColAttribute 返回的大小为 4 的 VARCHAR。一旦结果超过 3 位数,它将失败。严格来说,我认为这个 ODBC 驱动程序坏了,但我相信如果你升级你的 DBI 和 DBD::ODBC,它会解决这个问题。
    猜你喜欢
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 2021-07-03
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多