タケユー・ウェブ日報

Ruby on Rails や Flutter といったWeb・モバイルアプリ技術を武器にお客様のビジネス立ち上げを支援する、タケユー・ウェブ株式会社の技術ブログです。

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;
}