Можно ли использовать DBIx :: Class с хранимыми процедурами вместо таблиц? - PullRequest
5 голосов
/ 22 сентября 2011

Доступ к чтению из БД был предоставлен мне через хранимые процедуры mssql, которые возвращают наборы результатов, а не таблицы или представления.Но я хочу иметь возможность читать данные с помощью ORM.

Я пытался использовать DBIx::Class::ResultSource::View для выполнения вызова процедуры (например, EXEC my_stored_proc ?) как пользовательский запрос, но это не сработало, потому что он пыталсяпреобразовать вызов процедуры в оператор выбора.

У кого-нибудь есть другое предложение?

Ответы [ 2 ]

6 голосов
/ 09 мая 2012

Нет, разумного способа выполнить хранимую процедуру в контексте DBIx :: Class нет.

Насколько я могу судить, наиболее близким к обходному пути является "использование ORM" для получения дескриптора базы данных, что является слабым супом:

   my @results = $schema->storage->dbh_do(sub{
         my ($storage, $dbh, @args) = @_;
         my $sth = $dbh->prepare('call storedProcNameFooBar()');
         my @data;
         $sth->execute();
         while( my $row = $sth->fetchrow_hashref){
             push @data, $row;
         }
         return @data;
    },());

[подробности см. На http://metacpan.org/pod/DBIx::Class::Storage::DBI#dbh_do]

... поскольку вы не получаете ни одного из преимуществ ORM для вашей проблемы.

0 голосов
/ 23 сентября 2011

Вы можете использовать register_source

 package My::Schema::User;

  use base qw/DBIx::Class/;

  # ->load_components, ->table, ->add_columns, etc.

  # Make a new ResultSource based on the User class
  my $source = __PACKAGE__->result_source_instance();
  my $new_source = $source->new( $source );
  $new_source->source_name( 'UserFriendsComplex' );

  # Hand in your query as a scalar reference
  # It will be added as a sub-select after FROM,
  # so pay attention to the surrounding brackets!
  $new_source->name( \<<SQL );
  ( SELECT u.* FROM user u 
  INNER JOIN user_friends f ON u.id = f.user_id 
  WHERE f.friend_user_id = ?
  UNION 
  SELECT u.* FROM user u 
  INNER JOIN user_friends f ON u.id = f.friend_user_id 
  WHERE f.user_id = ? )
  SQL 

  # Finally, register your new ResultSource with your Schema
  My::Schema->register_source( 'UserFriendsComplex' => $new_source );

Для вызова с параметрами сделайте следующее

my $friends = [ $schema->resultset( 'UserFriendsComplex' )->search( {
+}, 
    {
      bind  => [ 12345, 12345 ]
    }
  ) ];
...