我在 PostgreSQL 表上使用用戶生成的輸入進行全文搜索,在本例中為“a”。
my $dbh = DBI->connect("...", { RaiseError => 0, AutoCommit => 1 });
my $sth = $dbh->prepare("SELECT name from mytable WHERE tsv @@ plainto_tsquery('the a')");
my $rv = $sth->execute();
如果用戶輸入僅包含停用詞,我會在 STDERR 上收到一條通知,并且查詢不回傳任何結果,但不會產生任何錯誤。
我想在 Perl 中捕獲該 NOTICE 以提醒用戶改寫搜索,但我似乎無法訪問它。
將 RaiseError 設定為 1 不會改變任何東西并且 $dbh->pg_notifying 回傳 undef。
有任何想法嗎 ?
uj5u.com熱心網友回復:
我認為提到“注意”意味著某事做了一個RAISE. 它的行為方式是可配置的,但深入研究需要更多細節。
在 perl 級別,有多種方法可以訪問STDERR流并捕獲發送給它的內容。
如果這些是警告,那么$SIG{__WARN__}每當要列印警告時,都會設定一個掛鉤來運行該子例程
{
local $SIG{__WARN__} = sub { say "Got warning: $_[0]"; };
warn "a warning...";
}
所以你可以用這種方式捕捉它,用它做你想做的事,然后也許重新發送。將$_[0]在本例中有串a warning,和匿名子后,運行控制回后的下一行warn...。見%SIG。
我把這個塊只能夠到當地-ize的變化SIG{__WARN__},有什么實際上是強制性的(如果全球不local-ized其變動被認為是在所有的代碼)。因此,如果此代碼在合適的詞法范圍內,則不需要該塊。
但這不會捕獲直接列印到STDERR. 為此,最實用的方法是使用庫,為此目的一個簡單方便的方法是Capture::Tiny
use Capture::Tiny qw(capture);
my ($stdout, $stderr, $exit) = capture {
say "to STDOUT";
say STDERR "to stderr";
warn "a warn-ing";
# ...
};
現在$stdout有文本to STDOUT,同時$stderr已to STDERR其次a warn-ing。因此,您的資料庫代碼將放在這樣的塊中,并且 NOTICE 應該在該$stderr變數中結束。capture_stderr如果您只想以這種方式捕獲,還有一個功能。
uj5u.com熱心網友回復:
這似乎不能正常作業,它被認為是一個未解決的錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/382515.html
標籤:PostgreSQL的 perl 错误处理
