使用 DBI 和 DBD 抑制连接错误:ODBC SQL Server Native Client 10.0
Posted
技术标签:
【中文标题】使用 DBI 和 DBD 抑制连接错误:ODBC SQL Server Native Client 10.0【英文标题】:Suppressing connection error with DBI and DBD:ODBC SQL Server Native Client 10.0 【发布时间】:2011-05-12 06:15:36 【问题描述】:编写脚本以从表中获取 SQL Server 实例名称,然后尝试连接到每个实例以获取数据库配置信息。涉及的所有数据库实例都是 SQL Server 的某个版本。如果连接失败(由于密码错误、实例关闭等),目的是打印用户定义的错误消息(“无法连接到 $inst,正在跳过。”)并继续浏览列表。我无法抑制来自 ODBC (SQL Server Native Client 10.0) 的默认错误消息。
这样尝试连接:
eval
my $dbh = DBI->connect(
"dbi:ODBC:Driver=SQL Server Native Client 10.0;Server=<instance_name>;Uid=<user_name>;Pwd=<password>;",
PrintError => 0, RaiseError => 1, AutoCommit => 1
);
;
我(可能不正确)理解 PrintError => 0 应该抑制错误消息,如果连接方法失败,RaiseError => 1 将导致 DBI 死掉,此时我可以检查 $@ 是否有错误并打印用户定义的消息。我也查看了 HandleError 属性,但没有任何成功。
这是一个完全不现实的场景,还是我正在使用的 ODBC 驱动程序的结果?
根据 bohica 的建议,工作代码如下所示:
eval
my $dbh = DBI->connect(
"dbi:ODBC:Driver=SQL Server Native Client 10.0;Server=<instance_name>;",
"Username",
"Password",
PrintError => 0, RaiseError => 1, AutoCommit => 1
);
;
用户名和密码已从连接字符串中移出,并作为单独的参数传递给 DBI 连接方法。
【问题讨论】:
您的示例中缺少用户名/密码参数,因此您的 DBI 属性的 hashref 将被视为用户名。仅仅因为您将 UID/PWD 放在连接字符串中并不意味着您可以省略 DBI 的第二个和第三个参数。 进行此更改产生了预期的结果,错误消息被抑制。 【参考方案1】:connect
是一个类方法;你用DBI->connect
调用它,它返回一个数据库句柄(在你的例子中是$dbh
)。
【讨论】:
对,这在我的代码中是正确的,但在帖子中却不是。谢谢!【参考方案2】:假设您解决了 Pedro 提到的问题,PrintError=>0 会抑制错误,您可能还想查看 PrintWarn。如果连接失败,则 RaiseError=>1 将导致连接终止,在您的示例中,错误将出现在 $@ 中。
【讨论】:
谢谢,PrintError 设置为 0。同时将 PrintWarn 设置为 0,没有任何变化。 RaiseError 设置为 1,但是当连接失败并且我在 eval 块之外检查 $@ 时,它是未定义的。 perl -le '使用 DBI;我的 $dbh; eval $dbh = DBI->connect("dbi:ODBC:baugi","sa","wrongpassword", PrintError => 0, PrintWarn => 0, RaiseError => 1);; print "错误是 $@\n";'错误是 DBI connect('baugi','sa',...) failed: [unixODBC][Easysoft][SQL Server Driver][SQL Server]用户 'sa' 登录失败。 (SQL-28000) 在 -e 第 1 行以上是关于使用 DBI 和 DBD 抑制连接错误:ODBC SQL Server Native Client 10.0的主要内容,如果未能解决你的问题,请参考以下文章
如何在自定义 @INC 中使用 DBI 构建 DBD::mysql?
Perl DBI Sybase Asanywhere 绑定变量问题
Perl DBD::ODBC 到 Informix DBMS