2009-02-04 11 views
6

Per fare un inserto con Class :: DBI, si può semplicemente fare:Come posso eseguire un aggiornamento in Class :: DBI senza prima selezionare un record?

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

ma non v'è nulla di simile per l'aggiornamento. Il meglio che ho potuto venire in mente è la selezione del primo record poi aggiornarlo:

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

Questo non è efficiente, in quanto devo fare un SELECT prima, e poi un UPDATE invece di uno solo UPDATE.

C'è un modo migliore per farlo con Class :: DBI? Non voglio fare 42 $ oggetto-> a (1), $ oggetto-> b (2), ecc., $ Oggetto-> aggiornamento;

+0

DBIx :: Class rende questo facile. Dovresti davvero prendere in considerazione l'idea di allontanarti da CDBI. – jrockway

risposta

6

Per quanto ne so, Class :: DBI non ha un buon modo per farlo, come hai notato, il suo metodo update() è pensato per essere chiamato su un oggetto che è stato precedentemente caricato dal database.

Si può essere in grado di convincere Class :: DBI di fare ciò che si vuole, tuttavia, con qualcosa di simile:

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

Se questa funzione è importante per voi e non siete già troppo lontano nel il tuo progetto, avrai sicuramente più fortuna con uno dei nuovi ORI Perl come Rose::DB::Object o DBIx::Class. DBIx :: Class include anche a Class::DBI compatibility layer.

4

Un modo che ho trovato di fare questo è di sovrascrivere la classe iteratore predefinita per i tuoi oggetti. Questo ti permette di avere una collezione di singoli oggetti con un metodo di aggiornamento sulla collezione. Class :: DBI fornisce un metodo per questo:

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

Questo ti permette di fare poi un metodo update nella classe iteratore che può salvare tutti gli oggetti della collezione. Come tale il tuo codice può apparire in questo modo:

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

Ciò che rende per alcuni codice piuttosto ben documentato. Se segui questo percorso, ti suggerisco anche di mettere in uso il metodo is_changed mentre si verifica l'aggiornamento(). Ti aiuterà a risparmiare tempo non aggiornando le righe non modificate.

Problemi correlati