Perl DBI语句句柄和错误处理

时间:2015-08-08 07:31:30

标签: perl dbi

我们说我有一个连接到DB的子程序。然后我想创建一个查询并接收输出并用它做一些事情,当然,但如果查询无效怎么办?

所以,让我们假设我有类似的东西:

$dbh = DBI->connect(<db>, <user>, <pass>);
$query = 'select a, b, c from table';
$sth = $dbh->prepare($query);
$sth->execute();

我意识到我也可以使用&#34; do&#34;,但这对我来说更容易理解。所以在&#34; table&#34;没有列&#34; c&#34;,查询将无效,使句柄$ sth无效并且无法执行。正确?

现在,如果发生故障,$ sth会发生什么?我无法通知它,因为它无效。

2 个答案:

答案 0 :(得分:5)

这是迄今为止最好的做事方式。坚持使用prepare(您只需执行一次)和execute并避免使用do。对于查询的任何参数,您还应将问号用作占位符,并将调用中的值传递给execute。除此之外,这种方式可以为您处理任何必要的值引用

很少需要拨打finishdisconnect。你应该把它们留下来,直到你知道你的方式DBI更好

您更正,$sth将为undef,错误代码和错误消息将由$dbh->err$dbh->errstr返回。此外,默认情况下会设置PrintError选项,如果执行中出现任何错误,则会导致DBI生成警告。如果您希望程序完全停止,请停用PrintError并启用RaiseError

除此之外,它确实取决于你在错误的情况下选择做什么。例如,某些错误可能是可恢复的,在这种情况下,您可以禁用 PrintError RaiseError并测试返回的值是否为{{ 1}}。然后,您可能会根据undef

返回的错误代码执行某些操作

我希望有帮助

答案 1 :(得分:5)

  

因此,在“table”没有列“c”的情况下,查询将无效,使得句柄$ sth无效并且无法执行。正确?

目前尚不清楚“无效”是什么意思。

某些驱动程序(如DBD :: Oracle)可能会在您调用prepare时将SQL语句发送到服务器,在这种情况下,服务器将检测到错误,prepare将失败,返回一个undef。 (另见@ Borodin关于RaiseError的说明。)

如果驱动程序 在调用prepare时将语句发送到服务器,则驱动程序创建并返回一个语句字符串,该语句字符串存储在其中。

  

现在,如果发生故障,$ sth会发生什么?我不能打电话给它,因为它无效。

同样,不清楚“无效”是什么意思。 (我发现尝试真正清楚我正在考虑的概念和情况是有帮助的。强迫自己这样做通常意味着我找到了自己问题的答案,因为'问题'是用我正在使用的词语。)

所以,正如我上面所描述的那样,prepare失败并返回undef(或由于RaiseError而引发异常 - 建议),或者prepare返回了有效的$ sth。

如果prepare返回了undef,那么当你尝试调用execute时,perl会抛出异常。

如果prepare返回有效的$ sth,则会调用execute,语句将被发送到服务器,服务器将检测到错误,execute将返回false(如果设置了RaiseError,则抛出异常 - 推荐)。

我决不会叫$ sth“无效”。要么你没有$ sth,因为准备失败了,或者你有一个完全有效但是在执行时遇到错误的$ sth。

在这种情况下,调用$sth->finish会起作用,但是,正如@ThisSuitIsBlackNot正确指出的那样,它将毫无意义。 (多年前我应该将finish重命名为discard_pending_rows。)