2011-09-22 15 views
5

El acceso para leer desde el archivo db me ha sido dado a través de mssql procedimientos almacenados que devuelven conjuntos de resultados en lugar de tablas o vistas. Pero quiero poder leer los datos usando ORM.¿Se puede utilizar DBIx :: Class con procedimientos almacenados en lugar de tablas?

Intenté usar DBIx::Class::ResultSource::View para hacer la llamada al procedimiento (por ejemplo, EXEC my_stored_proc ?) como una consulta personalizada, pero esto no funcionó porque intentó convertir la llamada al procedimiento en una instrucción select.

¿Alguien tiene otra sugerencia?

Respuesta

5

No, no hay manera razonable para ejecutar un procedimiento almacenado en el contexto de DBIx :: Clase.

Por lo que yo puedo decir, lo más parecido a una solución es "usar el ORM" para obtener un identificador de base de datos, que es débil sopa:

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; 
    },()); 

[ver detalles en http://metacpan.org/pod/DBIx::Class::Storage::DBI#dbh_do]

... ya que no obtiene ninguno de los beneficios de un ORM para su problema.

+0

La sección 'DBIx :: Class :: Manual :: Cookbook' docs 'Usar funciones de base de datos o procedimientos almacenados', aunque @stevenl ha señalado que no ayudará con MS SQL Server, ya que aparentemente no puede acceder a un procedimiento almacenado a través de una instrucción SELECT. – LeeGee

+1

ni Mysql, y supongo que tampoco es Oracle. Me pregunto si el autor del manual de DBIx: Class simplemente lo está inventando. – djsadinoff

+0

De hecho, ¿y cuál sería el comportamiento esperado? ¿Cómo sabría DBIC con qué ResultSet asociar los datos devueltos por el procedimiento o la función almacenados? Creo que el autor significaba 'función' como en la función SQL, como 'longitud' es el ejemplo. Eso no explica cómo se agregó el 'procedimiento almacenado'. – LeeGee

-2

Puede utilizar 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); 

Para llamar con parámetros haga lo siguiente

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

Esta solución es muy similar a lo que hice con ResultSource :: View. El problema con este enfoque es la parte donde agrega mi llamada sproc como una selección secundaria. La consulta generada se verá así: 'SELECT me.x FROM (EXEC my_stored_proc?) Me' que causa un error de sintaxis y la declaración no puede prepararse. Supongo que este problema no sería específico de mssql ya que tampoco veo otras plataformas que tengan una sintaxis compatible. – stevenl

+1

Esto no responde la pregunta. No hay un procedimiento almacenado aquí. – djsadinoff

Cuestiones relacionadas