2009-02-04 15 views
6

Para hacer un inserto con Class :: DBI, sólo tiene que hacer:¿Cómo puedo hacer una actualización en Class :: DBI sin seleccionar primero un registro?

my $object = Object::DB->insert({ a => 1, b => 2, c => 3, ...}); 

pero no hay tal cosa para la actualización. Lo mejor que podía llegar a es seleccionar el registro primero y luego actualizarlo:

my $object = Object::DB->retrieve($id); 
my $object->set(a => 1, b => 2, c => 3, ...}; 
$object->update; 

Esto no es eficiente ya que tengo que hacer un SELECT en primer lugar, y luego un UPDATE en lugar de sólo una actualización.

¿Hay una mejor manera de hacer esto con Class :: DBI? No quiero hacer 42 $ object-> a (1), $ object-> b (2), etc., $ object-> update;

+0

DBIx :: Class hace esto fácil. Realmente deberías considerar alejarte de CDBI. – jrockway

Respuesta

6

Por lo que sé, Class :: DBI no tiene una buena manera de hacer esto, Como habrás notado, su método update() debe invocarse sobre un objeto que se ha cargado previamente desde la base de datos.

Usted puede ser capaz de convencer Class :: DBI para hacer lo que quiere, sin embargo, con algo como esto:

# Make new "empty" object 
my $o = My::CDBI::Object->new; 

# Set the primary key column and discard the change 
$o->set(your_pk_column => 123); 
$o->discard_changes; 

# Set your other columns 
$o->set(a => 'foo', b => 'bar'); 

# Do the update 
$o->update; 

Si esta característica es importante para usted y aún no se encuentra demasiado lejos en su proyecto, definitivamente tendrá mejor suerte con uno de los más nuevos ORM Perl como Rose::DB::Object o DBIx::Class. DBIx :: Class incluso incluye a Class::DBI compatibility layer.

4

Una forma que he encontrado para hacer esto es anulando la clase de iterador predeterminada para sus objetos. Esto le permite tener una colección de objetos individuales con un método de actualización en la colección. Class :: DBI proporciona un método para esto:

__PACKAGE__->iterator_class('MyClass::CDBI::Iterator'); 

Esto le permite luego hacer un método update en la clase de iterador que puede salvar a todos los objetos de la colección. Como tal, su código puede ser algo como esto:

my $collection = Object::DB->search_where({id => {'>=', 0}}); 
foreach my $obj ($collection->next()) { 
    $obj->a('bob'); 
    $obj->b('tom'); 
} 
$collection->update(); 

que lo convierte en un código bastante bien auto-documentado. Si sigue esta ruta, también le sugiero que use el método is_changed a medida que ocurre la actualización(). Le ayudará a ahorrar tiempo al no actualizar las filas sin cambios.

Cuestiones relacionadas