22

将 DBIC_TRACE 环境变量设置为 true:

BEGIN { $ENV{DBIC_TRACE} = 1 }

生成非常有用的输出,特别是显示正在执行的 SQL 查询,但 SQL 查询都在一行上。

有没有办法通过某种“sql tidy”例程来更好地格式化它,也许将它分成多行?如果做不到这一点,谁能给我一个提示,我需要破解代码中的哪个位置来添加这样的钩子?最好的工具是接受格式错误的 SQL 查询并推出格式良好的查询?

在这种情况下,“漂亮的格式”仅仅意味着比“全部在一行上”更好。我对格式查询的特定样式并不特别在意

谢谢!

4

3 回答 3

21

从 DBIx::Class 0.08124 开始,它是内置的。

只需设置$ENV{DBIC_TRACE_PROFILE}consoleconsole_monochrome

于 2010-12-20T00:33:26.443 回答
10

来自 DBIx::Class::Storage 的文档

如果设置了 DBIC_TRACE,则生成跟踪信息(与设置调试方法时一样)。

...

debug
导致在 debugobj 对象上发出跟踪信息。(或 STDERR,如果没有专门设置 debugobj)。

debugobj
设置或检索用于度量收集的对象。默认为与使用 coderef 作为回调的原始方法兼容的 DBIx::Class::Storage::Statistics 实例。有关更多信息,请参阅前面提到的统计类。

换句话说,您应该debugobj在该类中设置一个子类DBIx::Class::Storage::Statistics的对象。在您的子类中,您可以按照您希望的方式重新格式化查询。

于 2009-02-17T12:41:33.620 回答
3

首先,感谢指点!部分答案如下......

到目前为止我所拥有的......首先是一些脚手架:

# Connect to our db through DBIx::Class
my $schema = My::Schema->connect('dbi:SQLite:/home/me/accounts.db');

# See also BEGIN { $ENV{DBIC_TRACE} = 1 }
$schema->storage->debug(1);

# Create an instance of our subclassed (see below)
# DBIx::Class::Storage::Statistics class
my $stats = My::DBIx::Class::Storage::Statistics->new();

# Set the debugobj object on our schema's storage
$schema->storage->debugobj($stats);

My::DBIx::Class::Storage::Statistics 的定义是:

package My::DBIx::Class::Storage::Statistics;

use base qw<DBIx::Class::Storage::Statistics>;
use Data::Dumper qw<Dumper>;
use SQL::Statement;
use SQL::Parser;

sub query_start {
    my ($self, $sql_query, @params) = @_;

    print "The original sql query is\n$sql_query\n\n";

    my $parser = SQL::Parser->new();
    my $stmt   = SQL::Statement->new($sql_query, $parser);
    #printf "%s\n", $stmt->command;

    print "The parameters for this query are:";
    print Dumper \@params;
}

这解决了有关如何挂钩以使我的 SQL 查询“漂亮化”的问题。

然后我运行一个查询:

my $rs = $schema->resultset('SomeTable')->search(
    {   
        'email' => $email,
        'others.some_col' => 1,
    },
    { join => 'others' }
);
$rs->count;

但是 SQL::Parser 对 DBIx::Class 生成的 SQL 不满意:

The original sql query is
SELECT COUNT( * ) FROM some_table me LEFT JOIN others other_table ON ( others.some_col_id = me.id ) WHERE ( others.some_col_id = ? AND email = ? )

SQL ERROR: Bad table or column name '(others' has chars not alphanumeric or underscore!

SQL ERROR: No equijoin condition in WHERE or ON clause

那么......有没有比 SQL::Parser 更好的解析器来完成这项工作?

于 2009-02-17T21:22:14.693 回答