IF-Abfrage in AR einfügen

Hallo und schönen 3. Advent,

wie kann man in einen AR eine IF-Abfrage einbauen? Ziel soll sein, dass ich folgendes hinbekomme:




IF(Spalte_1==true,Spalte_1,Spalte_2) AS Sortierbares_Ergebnis..... ORDER BY Sortierbares_Ergebnis



Dabei soll die obige Anweisung zusätzlich zur Default-Selection * hinzugefügt werden. Wenn ich das z.B. über eine Criteria mache ($criteria->select), dann wird mir nichts anderes mehr zurückgegeben.

Danke für alle Hinweise!

pixelpillar

wann soll die Abfrage denn gemacht werden? Vor dem Speichern?

Du könntest sowas in




public function onBeforeSave()

{

 //deine prüfungen

}



implementieren.

Für select Anweisungen musst du die Criteria Objekte mergen. Wie man sowas macht, kannst du dir in der Implementierung von CSort oder CPagination anschauen. Diese verändern auch ein übergebenes Criteria Object.

Die IF-Abfrage soll während eines normalen Selects erfolgen. Hier vielleicht zur Erklärung, in der eine Spalte ist der englische Titel, in der zweiten der deutsche Titel der als Default-Titel ausgegeben werden soll. Ist dieser aber nicht vorhanden, dann soll der englische genommen werden. Bei der Sortierung der gesamten Liste jedoch soll eben der Alias der Abfrage dienen. Sonst kann ich ja nicht dt. und engl. Titel am Stück sortieren.

Der Hinweis mit der Implementierung in der Pagination und Sort hat mich leider nicht weitergebracht, da hier -meiner Ansicht nach- die Criterias nicht gemerged werden, sondern die jeweiligen Attribute überschrieben werden. Merge ich die Attribute mit der mergeWith-Methode von CDbCriteria bekomme ich einen SQL-Fehler ("Note, the column must exist in the table or be an expression with alias") obwohl ich den Tabellenname vorangestellt habe.

Welche Lösung gibt es für so einen Fall? Wie kann ich einen Spalten-Alias im Model setzen?

Hab mal etwas rumgeforscht. Ist nicht so einfach, das in alle SELECTs einzuschleusen. Aber mit dem defaultScope könnte es klappen. Probiers mal, indem du folgendes zu deinem AR hinzufügst:


public $blabla;


public function defaultScope() {

    return array(

        'select'=>'*,IF(....) AS blabla',

    );

}

Achso, und wenn du’s nur für eine einzelne Abfrage brauchst, dann kannst du obigen String auch einfach im $criteria verwenden. Wichtig ist halt das “*,” am Anfang.

Hallo Mike,

ich habe als defaultScope die Abfrage + * eingefügt und ebenfalls mal in meine Criteria




$criteria = new CDbCriteria();

$criteria->select = '*, IF(mv_filme.mv_titel_de!="", mv_filme.mv_titel_de, mv_filme.mv_titel_en) AS mv_titel';



leider bekomme ich nach wie vor und bei beiden SQLs die Fehlermeldung




Active record "mv_filme" is trying to select an invalid column "*". Note, the column must exist in the table or be an expression with alias.



Dass er hier mit den Aliasen bzw. Spaltennamen durcheinanderkommt.

Was kann ich denn hier machen?

Hmm, hab grad gesehn, dass es bei mir auch nicht klappt, wenn ich with() verwende. Ohne gehts einwandfrei. Evtl. kannst ja da noch etwas im Yii-Code forschen. Mach ich auch, wenn ich wieder etwas Zeit find ;) .

Hab mir mal die CActiveFinder-Klasse angeschaut und hier die getColumnSelect-Methode. Der Fehler bzw. mein Problem liegt daran, dass der jeweilige Select mit einem explode auf ‘,’ (Komma) aufgeteilt wird. Folge ist dann, dass die IF-Abfrage in der ja 2 Kommata sind aufgeteilt wird und man dann in die Exception läuft dass kein Alias bzw. Spaltenname definiert wurde. That’s it!

Ich werde mal schauen ob man das umgehen kann bzw. ein Ticket o.ä. aufmachen.

Ah, wie Qiang hier schreibt, kann man die einzelnen Columns bei ‘select’ auch als Array, statt mit Komma getrennt übergeben. Hilft das was?

Ja, das könnte passen. Da bin ich gestern auch noch drauf gestoßen. Was ich jetzt noch benötige ist die Möglichkeit, dass ich der Tabelle des Models einen Alias vergeben kann. Den Relationen kann ich das ja, wie geht das aber für den eigentlich AR?

Soweit ich sehe geht das nicht. Siehe Quellcode in framework/db/schema/CDbCommandBuilder.php: createFindCommand.

Soweit ich das sehe, hast Du da leider recht! Hmm, das ist irgendwie ein Ding, wo ich mich langsam im Kreis drehe. Aber was soll’s, in der vorherigen Application hatte ich das Problem über einen SQL-View gelöst und war PHP-seitig damit auf der sicheren Seite. Das werde ich dann wohl wieder einführen!

Gruß,

pixelpillar

Du kannst ja auch ein AR für einen View machen. Funktioniert genauso.