【问题标题】:Why does my usage of Perl's DBI->connect fail silently?为什么我使用 Perl 的 DBI->connect 会静默失败?
【发布时间】:2010-01-11 22:55:35
【问题描述】:

为什么这段代码会静默失败?如何让它准确地显示 SQL 错误是什么?

$dbh=DBI->connect($db_name,$db_user,$db_pass);

我将代码修改为如下所示:

$dbh=DBI->connect($db_name,$db_user,$db_pass)
    or die("could not connect to db: $db_name");

它不允许我使用$dbh unassigned,而是会按预期失败,但它并没有告诉我它失败的确切原因。 $db_name 等的值,就我所见,都设置了有效值。

我知道真正的错误(MySQL 服务器实际上没有运行),但为了将来参考,我想看看真正的错误,以防我导致身份验证失败。

【问题讨论】:

  • 再次,请向我们展示完整的脚本(尽管屏蔽了用户名和密码!)。您最后几个问题的答案与您未显示的内容有关。
  • @brian 对不起。我不会再犯这个错误了。

标签: perl dbi


【解决方案1】:

您没有看到connect 失败的原因,因为您没有按照DBI 的指示进行操作。错误将在$DBI::errstr 变量中:

$dbh = DBI->connect($data_source, $username, $password)
     or die $DBI::errstr;

确保您阅读了有关您想要使用的任何函数或方法的文档。 :)

【讨论】:

  • Okie dokes,我以后就用这个了。
  • 我现在看到了你自己的答案。我怀疑你在我写它的同时发现了它,因为我认为你在我之前提交了你的答案。如果它是正确的(不是我在抱怨),请不要因为接受你的答案而感到难过:)
【解决方案2】:

啊哈,错误存储在$DBI::errstr,所以我可以像这样修改我的代码:

$dbh=DBI->connect($db_name,$db_user,$db_pass)
    or die("could not connect to db: $DBI::errstr");

根据文档,它设计为静默失败。

【讨论】:

  • @brian 啊,当然。我真是太傻了,我应该经常重新阅读文档以确保我不会遗漏任何内容。
【解决方案3】:

在连接时传递 RaiseError => 1 作为选项,那么您的脚本将因错误而死。我的 Perl 商店有一个标准配置:

{
  RaiseError => 1,
  PrintError => 0,
  AutoCommit => 1,
  mysql_auto_reconnect => 1,
}

【讨论】:

  • 不错。如何设置标准配置?
  • 可能有官方方式;你可以继承 DBI 并覆盖 connect 方法。我们的项目有自己的专用 DBH 分配模块,可以从 YAML 加载配置。
  • 我还将 DBI 内容隐藏在应用程序级代码后面。如果您决定稍后切换到 RoseDB 或其他东西,应用程序级代码将保持不变,尽管实现不同。无论是子类还是委托,它仍然隐藏细节,因此您的应用程序与其松散耦合。 :)
【解决方案4】:

这是我对rjh's answer 的用法。我想我更喜欢这个而不是 die 方法,但还不确定......

$dbh = DBI->connect($data_source, $username, $password, { RaiseError => 1 });

【讨论】:

    【解决方案5】:

    您使用“或”是语法错误。列出的代码根本不应该运行。

    你想要:

    $dbh=DBI->connect($db_name,$db_user,$db_pass) 
        or die("could not connect to db: $db_name");
    

    请注意,or die... 是原始语句的一部分,而不是新语句。

    【讨论】:

    • 糟糕,错字。好眼力。我现在已经纠正了这一点。但也许你的答案应该是评论?
    • 不要输入代码。剪切并粘贴您正在使用的实际代码。我已经提到过几次了,但是你有点浪费人们的时间来回答你提出的问题,比如语法错误,而不是显示你正在使用的实际代码。您可以获得更好的答案并减轻为您提供免费帮助的人的负担,所以请这样做。 :)
    • @brian 是的,您完全正确,很抱歉浪费了您的时间;我只能想象你是多么讨厌为此唠叨我。 ;)
    【解决方案6】:

    尝试包含 $!在你的死亡信息中。

    $dbh = DBI->connect($db_name, $db_user, $db_pass)
      or die("could not connect to db ($db_name): $!");
    

    $! in perldoc perlvar

    【讨论】:

    • 这无济于事,因为 DBI 没有设置 $!。请参阅文档:“如果连接失败(见下文),它将返回 undef 并同时设置 $DBI::err$DBI::errstr。(它确实没有明确设置 $!。)”跨度>
    猜你喜欢
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 2020-08-17
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 2010-09-25
    相关资源
    最近更新 更多