Ändern von Datensätzen in Tabelle ohne Primary Key

Hallo erst mal,

ich hab wirklich einen super Fehler entdeckt und mir fast alle Haare ausgerissen :P und zwar habe ich eine Tabelle ohne Primary Key definiert. Warum spielt mal zunächst keine Rolle. Sollte es doch noch wichtig sein, so kann ich auch darauf noch eine Antwort liefern.

Jedenfalls ermögliche ich dem User diese Daten eines Datensatzes zu ändern. Beim Speichern der Änderungen erhalte ich dann folgende Meldung und nichts wird gespeichert:

Spaltenname muss entweder ein String oder ein Array sein.

Es war mir bis gerade eben unklar, was mir diese Meldung sagen will. Mit wurde nach und nach bewusst, dass Yii die Daten ohne eindeutige Zuordnung nicht speichern kann, nur ist die Meldung alles andere als hilfreich.

mfg

armin

benutzt du die methode updateByPK()?

nein, eigentlich nur die save()-methode.

Yii kann den Datensatz nicht speichern, da man den Datensatz nach dem lesen nicht mehr zuordnen kann. Auf welcher Grundlage will man denn entscheiden welchen Datensatz man updaten will?

Die Fehlermeldung "Spaltenname muss entweder ein String oder ein Array sein." rührt wahrscheinlich daher, das Yii versucht die Primary Key Spalte dieser Tabelle zu finden. Da keiner existiert wird null zurück gegeben was dazu führt das der Spaltenname kein "String oder ein Array" ist. String für einen einfach Primary Key und Array für zusammengesetzte Schlüssel.

Interessant wäre an dieser Stelle dann nun, wo überall eine solche Meldung geworfen wird und dann kann ja die Meldung selbst angepasst werden, sodass diese verständlicher ist, oder?

Die Meldung an sich ist ja korrekt und auch angemessen. Ich vermute das es überhaupt keine Prüfung gibt, die sich auf das vorhanden sein von PK Spalte bezieht. Daher wird die allgemeine zurückgegeben. Das liegt vermutlich daran, dass eine Tabelle ohne PK keinen Sinn ergibt.

Naja ergibt eigentlich schon Sinn, Koppeltabellen muss man ja auch so befüllen ohne das man auf die ActiveRecord Objekte und Methoden zurückgreifen kann.

Hast du schon mal versucht die Sachen einfach so über ein Datenbankquery in die Datenbank zu schreiben wie es zum Beispiel auch im Blog Tutorial gemacht wird? So könntest du es Theoretisch ja auch Umsetzen.

protected function afterSave()


{


    if(!$this->isNewRecord)


        $this->dbConnection->createCommand(


            'DELETE FROM PostTag WHERE postId='.$this->id)->execute();


 


    foreach($this->getTagArray() as $name)


    {


        if(($tag=Tag::model()->findByAttributes(array('name'=>$name)))===null)


        {


            $tag=new Tag(array('name'=>$name));


            $tag->save();


        }


        $this->dbConnection->createCommand(


            "INSERT INTO PostTag (postId, tagId) VALUES ({$this->id},{$tag->id})")->execute();


    }


}

Auch bei Koppeltabellen gibt es einen Primary Key. Der kann einer der beiden FKs sein oder die Kombination aus beidem. Wenn man Mehrfachvorkommen haben möchte fügt man einen generischen Key ein um auch einzelne wieder löschen zu können.

Man könnte in diesem Fall auch mit einem LIMIT 1 beim DELETE arbeiten, allerdings halte ich dann einen generischen PK für weniger Aufwand zumal man dann auch nicht speziell implementiern muss. :)

Also Datenbanktabellen ohne einen PK machen eigentlich NIE Sinn.

Es muss ja nicht immer nur eine Spalte sein. Zum Beispiel kann ein zusammengesetzter Schlüssel als PK dienen. Wichtig ist nur, das die Spalte(n) Ihren Inhalt nicht mehr verändern. Der Loginname eines Anwenders könnte ein PK sein, aber nur dann, wenn der User diesen NIE WIEDER ädern kann.

Christian

Hmm… ich habe eine Tabelle, die alle Spalten des abstrakten Elternobjekts sowie die zusätzlichen Spalten der Kindobjekte beinhaltet, sowie einen Diskriminator zum entscheiden, welchen Objekts die aktuelle Spalte ist. Allerdings möchte ich keinen direkten Zugriff auf diese Tabelle, sondern habe für die Kindobjekte entsprechend Views eingerichtet und Regeln für Select, Insert und Update definiert. Naturgemäß definieren die Vies keinen eigenen Primary Key.

Das Problem ist, dass Yii nun meckert, dass es keinen PK gäbe und ich deshalb nicht mit den Views arbeiten kann. Was kann man da machen?