gpt4 book ai didi

Perl 错误:在串联中使用未初始化的值 $DBI::err

转载 作者:行者123 更新时间:2023-12-03 16:52:21 25 4
gpt4 key购买 nike

我编写了一个程序,使用 DBI 库将数据从 xml 文件导入 MariaDB。该过程有效,但我不明白为什么以下代码会给我消息:

use of uninitialized value $DBI::err in concatenation (.) or string at ...

这里是代码(缩写):

my $insert_art = $dbh->prepare(
"INSERT INTO odbb_articles (creation_dt,ref_data,comp_no)".
"VALUES (?,?,?)"
);
....
my $comp_no = $xpc->findvalue('./sr:ARTCOMP/sr:COMPNO',$node1);
....
$insert_art->execute($creation_dt,$ref_data,$comp_no)
or die "Fehler bei der Ausfuehrung: ".
"$DBI::err -> $DBI::errstr (odbb_articles $DBI::state)\n";

如果我插入代码

if ($comp_no eq "") { $comp_no = undef; }

就在$insert_art->execute 之前,该过程起作用。当元素 COMPNO 的 xml 文件中没有条目时,会发生此错误。如果我将它定义为undef,我可以避免它。我只是想知道

  1. 为什么 $comp_no 会导致这个问题
  2. 除了控制 $comp_no 是否为 ""并将其定义为 undef 之外,还有其他解决方案吗?

第二个问题的原因是如果有很多可能有空条目的变量/列,则避免 if 语句。

感谢您的帮助。

最佳答案

use of uninitialized value $DBI::err in concatenation (.) or string at ...

您看到的错误消息是 Perl 告诉您 $DBI::errundef。这不是因为您的 $comp_no 的值(value)。这只是您的程序正在执行的操作的结果。

因此,当您将空字符串传递给 comp_no 列时,数据库不喜欢这样。它抛出一个错误。 DBI 捕获该错误并将其传递。 $insert_art->execute 返回一个假值,or 的右侧被调用。那是你的

现在,在传递给 die 的字符串中,您放置了三个变量:

  • $DBI::错误
  • $DBI::errstr
  • $DBI::状态

根据 the DBI documentation , 这些等同于函数 $h->err, $h->errstr$h->state with $ h最后使用的句柄。让我们看看这些文档。

  • $h->err

    Returns the native database engine error code from the last driver method called. The code is typically an integer but you should not assume that.

    The DBI resets $h->err to undef before almost all DBI method calls, so the value only has a short lifespan. Also, for most drivers, the statement handles share the same error variable as the parent database handle, so calling a method on one handle may reset the error on the related handles. [...]

    这并没有说明什么时候可以undef

  • $h->errstr

    Returns the native database engine error message from the last DBI method called. This has the same lifespan issues as the "err" method described above.

    The returned string may contain multiple messages separated by newline characters.

    The errstr() method should not be used to test for errors, use err() for that, because drivers may return 'success with information' or warning messages via errstr() for methods that have not 'failed'.

    好的,这是文本。不要用它来测试特定的错误。你没有那样做。您只想在程序失败时提供调试输出。

  • $h->state

    Returns a state code in the standard SQLSTATE five character format. Note that the specific success code 00000 is translated to any empty string (false). If the driver does not support SQLSTATE (and most don't), then state() will return S1000 (General Error) for all errors.

    The driver is free to return any value via state, e.g., warning codes, even if it has not declared an error by returning a true value via the "err" method described above.

    The state() method should not be used to test for errors, use err() for that, because drivers may return a 'success with information' or warning state code via state() for methods that have not 'failed'.

    同样,关于它的用处还不是很清楚。

我的建议是去掉 $DBI::err$DBI::state。你不需要那些来弄清楚问题是什么。只需输出 $DBI::errstr

$insert_art->execute($creation_dt,$ref_data,$comp_no)
or die "Fehler bei der Ausfuehrung: " . $dbh->errstr;

现在你的程序仍然会失败,但至少你会得到一条有意义的错误消息,它会解释你的数据库不喜欢该语句的地方。这比被告知错误处理代码中存在错误要好。

之后,其他答案可能适用于解决第一种情况下发生这种情况的原因。


另一方面,关于 die 的一句话:如果您在参数末尾提供 \n,它不会打印您当前的脚本、行号和输入句柄行号。但是这些可能对您有用。您可以包括它们。

关于Perl 错误:在串联中使用未初始化的值 $DBI::err,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34131741/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com