私はかなり奇妙な問題を抱えています。
これは少しXY問題なので、最初に「X」について説明します。
質問X:Perlを使用してDBI内部をデバッグするにはどうすればよいですか?
より具体的には、DBIのdb_error_handlerへの呼び出し。SQLサーバーのコールバック出力の一部は(クエリプラン)100%の時間で出力されますが、一部(実際のIO)は、クエリがゼロ行(とset statistics io on
)を返した場合にのみ出力されます。
究極の問題Y私が対処しようとしているのは:
何らかの理由で、私のPerlスクリプトはクエリプランを出力しますが、クエリが結果セットを返すときにSybaseクエリを実行するときに費やした実際のIOは出力しません。ただし、同じクエリがゼロ行を返したときに費やされたクエリプランと実際のIOの両方を出力します。
私は、本質的にこれを行うスクリプトを持っています:
sub DoSql { # Sql execution wrapper
my ($dbh, $sql) = @_;
my $sth = $dbh->prepare($sql);
$sth->execute();
}
# Set up DB connection, with debug printing turned on
my $dbh = CreateDBH(); # Uses DBI and creates Sybase database handle DBI object
$dbh->DoSql("set statistics io on");
$dbh->DoSql("set showplan on");
# Print output from DBH callback
$dbh->{_db_error_handler} = sub { PrettyPrintSybaseDebug($_[6]); }
$dbh->DoSql("SELECT * FROM MyTable WHERE ID=100"); # 1 row returned
$dbh->DoSql("SELECT * FROM MyTable WHERE ID=987654321"); # zero rows
このスクリプトを実行すると、最初のクエリはdb_error_handlerから次のSybase出力を出力します。
QUERY PLAN FOR STATEMENT 1 (at line 1).
STEP 1
The type of query is SELECT.
.....
Total estimated I/O cost for statement 1 (at line 1): 80.
ただし、2番目のクエリは次のSybase出力を出力します(追加された最後の3行を参照)。
QUERY PLAN FOR STATEMENT 1 (at line 1).
STEP 1
The type of query is SELECT.
.....
Total estimated I/O cost for statement 1 (at line 1): 80.
Table: MyTable scan count 1, logical reads: (regular=3 apf=0 total=3), ...
Total actual I/O cost for this command: 6.
Total writes for this command: 0
isql
これらのクエリをrawで実行すると、予想どおり、両方とも、プランとテーブルごとのスキャン数および実際のIOの両方を出力することに注意してください。両方のクエリは正常に実行され、期待される結果セットを生成します(それぞれ1行と0行)
何が間違っているので、どうすればこれをデバッグできますか?残念ながら、私は外の呼び出しと内のコールバックperl -d
しかデバッグできないので、私を助けません。$sth->execute();
重要な場合、私の環境は次のとおりです。
- Perl 5.8.0
- Solaris 10
- Sybase ASE 12.5
- DBIバージョンは1.37です