元フリーエンジニアライフ

Ruby on Rails とか MovableType とかAWSやってるフリーランスウェブエンジニアの記録でした。現在は法人成りしてIT社長。

MTのデータベースで任意のSQLを実行して結果を取得する

MT::Object->driver()を使う。

my $sql = "SELECT * FROM mt_entry WHERE entry_id = ?";
my @bind_values = ( 100 );
require MT::Object;
my $driver = MT::Object->driver;
my $dbh = $driver->rw_handle;
my $sth = $dbh->prepare( $sql );
die $dbh->errstr if $dbh->errstr;
$sth->execute( @bind_values );
die $sth->errstr if $sth->errstr;

実際の利用

以前実行した結果を連想配列の配列で取得するサブルーチンを書いたので晒しておきます。 どうぞご自由に。

使い方

my @results = find_by_sql( "SELECT entry_blog_id, COUNT(entry_id) FROM mt_entry WHERE entry_status = ? GROUP BY entry_blog_id", [2] );
print Data::Dumper->Dump([ \@results ]);
# =>
# [
#   {
#     'COUNT(entry_id)' => '1',
#     'entry_blog_id' => '1'
#   },
#   {
#     'COUNT(entry_id)' => '6',
#     'entry_blog_id' => '3'
#   },
#   {
#     'COUNT(entry_id)' => '213',
#     'entry_blog_id' => '4'
#   }
# ]

コード

sub find_by_sql {
    my ( $sql, $bind_values ) = @_;
    die unless $sql;
    $bind_values ||= [];

    my @result_set;

    require MT::Object;
    my $driver = MT::Object->driver;
    my $dbh = $driver->rw_handle;
    my $sth = $dbh->prepare( $sql );
    die $dbh->errstr if $dbh->errstr;
    $sth->execute( @$bind_values );
    die $sth->errstr if $sth->errstr;

    my @row;
    my $column_names = $sth->{ NAME_hash };
    my @next_row;
    @next_row = $sth->fetchrow_array();
    while ( @next_row ) {
        @row = @next_row;
        my $result = {};
        foreach my $column_name ( keys %$column_names ) {
            my $idx = $column_names->{ $column_name };
            $result->{ $column_name } = $row[ $idx ];
        }
        push @result_set, $result;

        @next_row = $sth->fetchrow_array();
    }
    $sth->finish();

    return wantarray ? @result_set : scalar \@result_set;
}