我有一个相当奇怪的问题。
这有点XY问题,所以我将首先描述“X”。
问题 X:如何使用 Perl 调试 DBI 内部?
更具体地说,对 DBI 的 db_error_handler 的调用。某些 SQL Server 回调输出会在 100% 的时间内打印(查询计划),但某些(实际 IO)仅在查询返回零行(带有set statistics io on
)时才打印。
终极问题 Y 我试图解决:
出于某种原因,当查询返回结果集时,我的 Perl 脚本会打印查询计划,但不会打印执行 Sybase 查询时花费的实际 IO ;但是,当 SAME 查询返回零行时,打印查询计划和实际花费的 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.
但是第二个查询打印以下 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
请注意,当我在 raw 中执行这些查询时isql
,它们都按预期打印计划和每个表的扫描计数和实际 IO。两个查询都运行良好并产生预期的结果集(分别为 1 行和 0 行)
我做错了什么,我该如何调试?不幸的是,perl -d
这对我没有帮助,因为我只能调试外部$sth->execute();
调用和回调内部。
如果重要的话,我的环境是:
- Perl 5.8.0
- 索拉里斯 10
- Sybase ASE 12.5
- DBI 版本为 1.37