Perl DBI 语句句柄和错误处理

Perl DBI Statement Handles and Error Handling

假设我有一个连接到数据库的子例程。然后我想进行查询并接收输出并对其进行处理,当然,但是如果查询无效怎么办?

所以让我们假设我有这样的东西:

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

我知道我也可以使用 "do",但这对我来说更容易理解。因此,在 "table" 没有列 "c" 的情况下,查询将无效,从而使句柄 $sth 无效并无法执行。对吗?

现在,万一出现这样的故障,$sth 会怎样?我无法对其调用 finish,因为它无效。

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

很少需要调用 finishdisconnect。你应该把它们排除在外,直到你更好地了解周围的道路DBI

你是对的,$sth将是undef,错误代码和错误信息将由$dbh->err$dbh->errstr返回。此外,默认设置了 PrintError 选项,这会导致 DBI 在执行过程中出现任何错误时生成警告。如果您希望您的程序完全停止,请禁用 PrintError 并启用 RaiseError

除此之外,这真的取决于您在出现错误时选择做什么。例如,某些错误可能是可恢复的,在这种情况下,您可以禁用 both PrintError and RaiseError 并测试是否返回值为 undef。然后,您可能会根据 $dbh->err

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

希望对您有所帮助

So in a scenario where "table" doesn't have a column "c", the query would be invalid, making the handle $sth invalid and failing to execute. Right?

不清楚你说的 "invalid" 是什么意思。

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

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

Now, in case of a failure as such, what happens to $sth? I can't call finish on it, because it is invalid.

同样,"invalid" 的意思不明确。 (我发现尝试 真正 清楚我正在思考的概念和情况很有帮助。强迫自己这样做通常意味着我找到了自己问题的答案,因为 'problem' 是我用的词。)

因此,正如我上面所描述的,prepare 失败并 returned 一个 undef(或由于 RaiseError 抛出异常 - 推荐),或者 prepare return输入了一个有效的$sth.

如果 prepare return 编辑了一个 undef 那么当你尝试调用 execute 时 perl 会抛出一个异常。

如果prepare return输入了一个有效的$sth然后execute将被调用,语句将被发送到服务器,服务器将检测到错误,并且execute 将 return false(或者如果设置了 RaiseError 则抛出异常 - 推荐)。

我绝不会调用$sth "invalid"。要么因为准备失败而根本没有 $sth,要么你有一个完全有效但在执行时遇到错误的 $sth。

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