2009-02-04 3 views
6

ein Insert mit Klasse zu tun :: DBI, können Sie einfach tun:Wie kann ich ein Update in Class :: DBI durchführen, ohne zuerst einen Datensatz auszuwählen?

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

Aber es gibt nicht so etwas für die Aktualisierung. Das Beste, was ich tun konnte, ist die Auswahl der Datensatz zuerst dann Aktualisierung:

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

Das ist nicht effizient, da ich zum ersten Mal eine SELECT zu tun haben, und dann eine UPDATE statt nur einer UPDATE.

Gibt es eine bessere Möglichkeit, dies mit Class :: DBI zu tun? Ich will nicht 42 $ object-> a (1), $ object-> b (2) usw., $ object-> update;

+0

DBIx :: Class macht das einfach. Sie sollten wirklich in Betracht ziehen, von CDBI wegzugehen. – jrockway

Antwort

6

Soweit ich weiß, Class :: DBI hat keine gute Möglichkeit, dies zu tun, wie Sie festgestellt haben, ist seine update() Methode für ein Objekt, das zuvor aus der Datenbank geladen wurde.

Sie können hier Class :: DBI davon zu überzeugen, zu tun, was Sie wollen, aber mit etwas wie folgt aus:

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

Wenn diese Funktion für Sie wichtig ist und Sie nicht bereits zu weit in Ihr Projekt, Sie werden definitiv mehr Glück mit einem der neueren Perl ORMs wie Rose::DB::Object oder DBIx::Class haben. DBIx :: Class enthält sogar a Class::DBI compatibility layer.

4

Eine Möglichkeit, die ich gefunden habe, besteht darin, die Standard-Iterator-Klasse für Ihre Objekte zu überschreiben. Auf diese Weise können Sie eine Sammlung einzelner Objekte mit einer Aktualisierungsmethode für die Sammlung erstellen. Class :: DBI stellt ein Verfahren hierfür:

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

Damit können Sie dann eine update Methode in der Iterator-Klasse zu machen, die alle Objekte in der Sammlung zu speichern. Ihr Code sieht also etwa so aus:

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

Das macht für einige ziemlich gut selbst dokumentierten Code. Wenn Sie diesen Weg gehen, würde ich auch empfehlen, die is_changed Methode zu verwenden, während das update() auftritt. Es hilft Ihnen, Zeit zu sparen, indem Sie die unveränderten Zeilen nicht aktualisieren.

Verwandte Themen