【问题标题】:Perl DBD fetchrow_array error:Perl DBD fetchrow_array 错误:
【发布时间】:2013-12-19 10:17:16
【问题描述】:

我在阅读 MySQL 时遇到了一些奇怪的错误,我的代码是这样的:

my $sql = <<"sqleof";
select t1.name t1_name, t2.name t2_name from t2
    inner join t1 using(Id)
    where t2.Id in (select Id from t3 where t3Id='$id') 
sqleof
#here $dbh had connected correctly and done some query before this; $sql can execute pretty well on MySQL command line and return me some records.
my $execute = $dbh->prepare($sql);
$execute->execute or die "Error: $DBI::errstr\n";
my @client = $execute->fetchrow_array() or die "Error: $DBI::errstr\n";
#here I got error saying: DBD::ODBC::st fetchrow_array failed:     Unable to fetch information about the error

有什么问题?

大家好,很抱歉打扰您。我找到了原因。这是一个低级别的错误,因为我使用了多个 $dbh 并且我弄错了执行名称。

    my $execute_A = $dbh->prepare($sql);
$execute_A->execute or die "Error: $DBI::errstr\n";
my @client = $execute_B->fetchrow_array()  #$execute_B here when I copied lines and modified.

您的帮助对我来说非常重要。谢谢大家。

【问题讨论】:

  • 您已标记 mysql 并且错误提示您将它与 ODBC 一起使用,这是非常不寻常的设置。
  • 我使用 Windows ODBC 数据源管理员创建了 DSN,并且 DSN 使用 MySQL ODBC 连接器连接远程数据库。你的 cmets 对我很有价值。

标签: mysql perl


【解决方案1】:

替换

my @client = $execute->fetchrow_array() or die "Error: $DBI::errstr\n";

与

my @client = $execute->fetchrow_array();

您正在获取空数组,这不适合 ..or die .. 建议的错误检查。

.. or die .. 仅对 prepare 和 execute 方法有意义。


旁注,您也缺乏适当的错误检查:

my $execute = $dbh->prepare($sql) or die $dbh->errstr; # not $DBI::errstr
$execute->execute or die $execute->errstr;             # not $DBI::errstr

另外,使用 sql 占位符 来防止sql injection。

【讨论】:

  • 不是完全正确,您不应该对fetch 方法进行错误检查(但您不使用or die 是对的)。来自DBI docs: "如果没有更多行或发生错误,则 fetchrow_array 返回一个空列表。您应该检查 $sth->err afterwards (或使用 RaiseError属性)来发现返回的空列表是否是由于错误造成的。”(强调我的)
  • @ysth 但在使用多个 DBI 实例时意义不大
  • 我在命令行上复制并运行了 $sql,可以返回 5 条记录。所以我不知道为什么要获取空数组。
  • $sth->err 返回“1”,$DBI::errstr 返回无法获取有关错误的信息。对我来说似乎没有更多有用的信息了。
  • @anaconda_wly 查询是否在命令行上返回某些内容?尝试$dbh-&gt;{RaiseError} = 1; 进行自动错误检查。
【解决方案2】:

尝试将 sql 查询中的变量 $id 更改为 ?然后通过执行传递变量。比如 $execute->execute($id)

【讨论】:

    【解决方案3】:

    在我看来,执行会导致您的 mysql 服务器崩溃。这是我能想到的唯一原因,可以解释“无法获取有关错误的信息”。如果您使用的是 safe_mysqld,您可能甚至不会注意到,因为它会自动重新启动。

    如果这是在一个网站上,并且您偶尔会收到此错误,那么有人试图通过在您的表单中输入3' or 'a'='a 之类的内容来破解您(尝试如果您将 id 替换为该字符串会发生什么情况)你的问题)。如果格式错误,服务器可能会尝试执行任何操作。为了防止这种 SQL 注入攻击,请将您的查询重写为

    my $sql = <<"sqleof";
    select t1.name t1_name, t2.name t2_name from t2
        inner join t1 using(Id)
        where t2.Id in (select Id from t3 where t3Id=?) 
    sqleof
    

    并致电$execute-&gt;execute($id)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-19
      • 2011-08-23
      • 2012-12-18
      • 2011-10-14
      • 2019-02-09
      • 1970-01-01
      相关资源
      最近更新 更多