Pqxx - SELECT bricht bei NULL Werten ab

Folgender Code dient dem Eintragen von Daten eines SELECT in ein wxGrid

work W(conn2);
        result vorg(W.exec(sql3));
        for (result::const_iterator c = vorg.begin(); c != vorg.end(); ++c) {
                int row = c - vorg.begin();         //extrahiere int aus Iterator
                
                int vnr = (c[0].as<int>());         //VID
                std::string svnr = std::to_string(vnr);
                Grid1->SetCellValue(row,0,svnr);
                
                string dat = (c[1].as<string>());   //Datum
                Grid1->SetCellValue(row,1,dat);
                
                string vanr = (c[2].as<string>());  //VANR
                Grid1->SetCellValue(row,2,vanr);
                
                ...

Es folgt ein weiteres Datumsfeld, das auch leer sein kann, weil der Eintrag später erfolgt.
Dort bricht das SELECT ab wenn es leer ist, ich habe mit IS_NULL und auch mit

      if (c[7].as<string>().length = 0) {
                string mdat = "none";
                } 
                string mdat = (c[7].as<string>());
                Grid1->SetCellValue(row,7,mdat);

versucht das abzufangen, ohne Erfolg. Bei allen anderen Spalten der Tabelle ist das Problem mit
dem Setzen von NOT NULL und eines Default-Wertes leicht zu umgehen, aber wie mache ich das bei
einem Datum. Es soll NOT NULL, aber trotzdem möglichst leer sein.

Ein Select bricht bestimmt nicht ab. Auch nicht, weil irgendwas NULL ist.
Meinst Du vielleicht:
Dein Programm bricht ab, weil eine Fehler (wegen ungültiger Datumsbehandlung von NULL Werten) nicht behandelt wird?

???
Sowas bekommst Du vielleicht mit einem Stringfeld hin, aber nicht mit einem Datum.

Ich denke du musst das mit

if (c[7].is_null())
{
...
}

machen :slight_smile:
Auch legst du eine lokale Variable mdat an (in der if Abfrage) welche sofort zerstört wird. Danach legst du eine weitere Variable an welche dann den Zugriff als as<string> macht und dann den Zugriff auf das null macht und eine Exception wirft.

@pogomips
du hast recht, das Select bricht nicht ab. Der Code bis zum Datenbank-SELECT wurde immer ausgeführt, der restliche Code und das Füllen der Tabelle aber nur, wenn es in der Datumsspalte keine Felder mit NULL gab, ansonsten kam der Fehler und die Tabelle blieb leer.
@schorsch_76
ich habe jetzt folgendes getestet:

                string zedat ;
                if (c[7].is_null()) {
                    string zedat = "none";
                    } else {
                        string zedat = (c[7].as<string>());
                    }
                    Grid1->SetCellValue(row,7,zedat);

Beim Kompilieren keine Fehler. Das SELECT wird auch ausgeführt, wenn es Felder mit NULL gibt. Allerdings funktioniert es nicht wie gewünscht, weil, egal ob die betreffende Spalte ein oder mehrere Felder mit NULL enthält oder vollständig ein Datum enthält, die gesamte Datumsspalte in der Tabelle bleibt leer. Leider scheint

 if (c[7].is_null()) {

und er Rest der Verzweigung ohne Wikung zu bleiben. Setze ich oben string zedat = "xxx"; so wird das in allen Rows des ResultSet ausgegeben.

hallo,
da ich heute wieder etwas mehr Zeit hatte, habe ich eine Lösung versucht, die mir als Ausweg erschien. Ich habe per psql UPDATE alle NULL Felder auf ‘01.01.1900’ gesetzt, ebenso als Standardwert für diese Spalte. Dann diesen Code

        ...
                string zedat = (c[7].as<string>());                
                if (zedat == ("01.01.1900")) {
                Grid1->SetCellValue(row,7,"---");
                } else {
                    Grid1->SetCellValue(row,7,zedat);
                    }
         ...

das funktioniert, damit ist die Lösung gefunden. Danke nochmal für alle Hinweise.

Edit: Der Vollständigkeit halber: Um das Format z.B. ‘01.01.1900’ zu erhalten sieht der betreffende Teil der SQL-Anweisung so aus:

SELECT ..., TO_CHAR(vorgang.zedat, 'DD.MM.YYYY') AS zedat ... FROM ...

Ohne diese Formatierung würde 1900-01-01 zurückgegeben und das müsste dann auch in der if Anweisung so stehen.

Das kann aber Seiteneffekte haben, wenn anderer Code von NULL ausgeht oder davon, dass eingetragene Datumswerte eine echte Bedeutung haben.
Wieso prüfst Du in Deinem Client Code nicht auf IS NULL, statt auf die 1.1.1990?

@pogomips
So, endlich
mit einer richtig gestalteten if … else Anweisung funktioniert auch das is_null

                    if (c[7].is_null()) {
                         Grid1->SetCellValue(row,7,"---");
                    } else {
                        string zedat = (c[7].as<string>());     
                        Grid1->SetCellValue(row,7,zedat);
                    }

Habe das Setzen des Wertes ‘01.01.1900’ bei is_null und als Default wieder entfernt.
Danke nochmal für alle Hinweise.

1 „Gefällt mir“

Dieses Thema wurde automatisch 60 Tage nach der letzten Antwort geschlossen. Es sind keine neuen Antworten mehr erlaubt.