Michi: Datetime = NULL

Hallo zusammen

Ich schreibe in meine Datenbanktabelle ein bestimmtes Datum in ein datetime Feld. Nun kommt es aber auch vor, dass das Feld leer bleibt.
Wenn ich keinen Wert eintrage, setzt die Datenbank einfach 01.01.1900 ein...was leider nicht sehr toll ist!
Er macht das auch, wenn ich der Datumsvariable sage: $datum = '' oder $datum = 'NULL'. NULL ist erlaubt.

Hat jemand ein Tipp, wie ich dem Tabellefeld sage, es ist NULL!

Danke für eure Tipps.
Gruss
Michi

  1. hi,

    Er macht das auch, wenn ich der Datumsvariable sage: $datum = '' oder $datum = 'NULL'.

    Warum willst du den Textstring 'NULL' dort eintragen?
    Wie meinst du, sollte der sich in ein gültiges Datum umwandeln lassen.

    NULL ist erlaubt.

    Dann benutze doch auch NULL.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. NULL ist erlaubt.

      Dann benutze doch auch NULL.

      Und wie mache ich den das? $datum = NULL ?

      Danke und Gruss
      Michi

      1. Hi,

        Und wie mache ich den das? $datum = NULL ?

        du machst hier gerade den Fehler PHP (?) und SQL vermischen zu wollen.
        Aus Sicht von PHP ist $datum="NULL" angemessen, damit dort ersteinmal die Zeichenfolge NULL drinsteht.
        Für die Datenbank ist aber nur entscheidend, was hinterher im SQL-Statement steht.
        Da ist zwischen spalte = 'NULL' und spalte = NULL ein großer Unterschied, nämlich genau der, den wahsaga dir oben genannt hat. Die Frage ist also aus meiner Sicht weniger wie du die PHP-Variable handhabst als vielmehr wie du sie hinterher im Statement einsetzt.

        MfG
        Rouven

        --
        -------------------
        ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
        1. Für die Datenbank ist aber nur entscheidend, was hinterher im SQL-Statement steht.

          OK, verstehe....

          Da ist zwischen spalte = 'NULL' und spalte = NULL ein großer Unterschied, nämlich genau der, den wahsaga dir oben genannt hat. Die Frage ist also aus meiner Sicht weniger wie du die PHP-Variable handhabst als vielmehr wie du sie hinterher im Statement einsetzt.

          Dann werde ich mal mein Statement genauer unter die Lupe nehmen...hoffe kriege es jetzt hin.

          Danke und Gruss
          Michi

        2. Da ist zwischen spalte = 'NULL' und spalte = NULL ein großer Unterschied, nämlich genau der, den wahsaga dir oben genannt hat. Die Frage ist also aus meiner Sicht weniger wie du die PHP-Variable handhabst als vielmehr wie du sie hinterher im Statement einsetzt.

          Kann ich in einem INSERT Query ein case when benutzen? Bei Google findet man den case when nur bei SELECT Abfragen. Und bei meinem SQL Statemant funktioniert er leider nicht.

          Danke für weitere Tipps.
          Gruss
          Michi

          1. Hi,

            na ja, so genau kann ich dir das leider nicht sagen...Aber brauchst du wirklich ein CASE nur des NULL-Wertes wegen?

            MfG
            Rouven

            --
            -------------------
            ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
            1. na ja, so genau kann ich dir das leider nicht sagen

              schade eigentlich ;-) aber macht nichts!

              »»...Aber brauchst du wirklich ein CASE nur des NULL-Wertes wegen?
              Ja, weil ich müsste ja im SQL Statement sagen, schreib eine NULL wenn die Variable leer ist aber schreib das gewünschte Datum, wenn die Variable nicht leer ist.

              Habe es jetzt aber anders gelöst. Sicher nicht schön sauber, aber immerhin läufts.
              Nach dem INSERT mache ich gleich nochmals ein UPDATE auf den Datensatz mit mit dem Datum 01.01.1900 und wenn dem so ist, setzt es auf NULL:
              update1 = mssql_query("UPDATE lizenzen SET datum = NULL WHERE datum = '01.01.1900'");

              Danke und Gruss
              Michi

              1. Hi,

                na ja, eigentlich bietet dir das PHP außen herum die Möglichkeit das Statement an dieser Stelle hinreichend zu beeinflussen. Ich gehe jetzt mal nicht auf diese ominösen Backticks (`) von MySQL ein, die sind mir nicht ganz geheuer... Aber der einzige Unterschied wäre ja, ob dort ein 'xyz' oder eben etwas ohne '' steht. Demnach könnte man diese Entscheidung ja in PHP verlagern:
                if ( [ es gibt kein Datum ] )
                   $datum = "NULL"
                else
                   $datum = "' ... '";
                            ^^ der String bringt also die Quotes selbst mit

                -> im SQL Statement erscheint dann bei Einsatz von $datum:
                "spalte = ".$datum
                --> "spalte = NULL" oder "spalte = ' ... '"

                MfG
                Rouven

                --
                -------------------
                ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
                1. echo $begrüßung;

                  Ich gehe jetzt mal nicht auf diese ominösen Backticks (`) von MySQL ein, die sind mir nicht ganz geheuer...

                  Was ist daran ominös, einen String von einem Bezeichner anhand der Quotierung zu unterscheiden? Andere DBMS machen das genauso, nur dass sie andere Zeichen nehmen.

                  echo "$verabschiedung $name";

                  1. Hi,

                    Was ist daran ominös, einen String von einem Bezeichner anhand der Quotierung zu unterscheiden? Andere DBMS machen das genauso, nur dass sie andere Zeichen nehmen.

                    genau das macht sie ominös. Wenn ich bei der Implementierung davon ausgehe, dass ich diesen Backtick nutzen kann lande ich bei einer Anwendung deren Portierung auf eine andere Datenbank extrem aufwändig ist. Ich ziehe aus diesem Grund mittlerweile die Methode mit den Parametern von Statements bei JDBC oder ADO vor, da hier der entsprechende Treiber die Erkennung der entsprechenden Typeigenheiten übernimmt. Aber gerade bei PHP dürfte es (ok, ich hab mich nicht ganz tief eingearbeitet...) Gang und Gebe sein, die Statements im Skript und nicht einem (austauschbaren) Datenbankobjekt zu lagern, so dass alle von Hand nachgezogen werden müssen.
                    Ich sehe ja durchaus den Vorteil, ich kenne Leute die Vergeben Tabellennamen mit Leerzeichen, da kommt man um sowas gar nicht umher, aber bei Access nach xyz müsste ich trotzdem [ ] durch irgendwas anderes ersetzen - sehr teuer. Ich ziehe es deshalb vor die Modelle so aufzubauen, dass eine derartige Syntax nicht erforderlich ist.

                    MfG
                    Rouven

                    --
                    -------------------
                    ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
                    1. hi,

                      Ich ziehe aus diesem Grund mittlerweile die Methode mit den Parametern von Statements bei JDBC oder ADO vor, da hier der entsprechende Treiber die Erkennung der entsprechenden Typeigenheiten übernimmt.

                      Mit der mysqli-Erweiterung kommt man dem in PHP zumindest schon mal etwas näher.

                      Da muss man der Methode bind_param() zwar immer noch den Typ des Parameters angeben - aber man muss nicht mehr schon in der Query die Entscheidung treffen, ob nun Anführungszeichen um den Wert gehören oder nicht.

                      gruß,
                      wahsaga

                      --
                      /voodoo.css:
                      #GeorgeWBush { position:absolute; bottom:-6ft; }
                      1. Hi wahsaga,

                        as der Funktionsblock sieht ja recht interessant aus, muss ich mir auf jeden Fall für die Zukunft mal merken, dass es sowas gibt. Erspart einem das auch endlich das  escapen? Ich habe gerade mysqli_real_escape_string gefunden, in den Beispielen arbeiten sie nur mit handgeschriebenen Queries, aber nicht mit prepared statements. Eigentlich dürfte es so ja keinen Grund mehr für Maskierung geben...

                        MfG
                        Rouven

                        --
                        -------------------
                        ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
                        1. hi,

                          Erspart einem das auch endlich das  escapen?

                          Ja, tut es wohl.
                          Wird in der Doku nicht erwähnt, aber die ist ja generell noch etwas spärlich.

                          Ich habe es aber mit ein paar Beispielwerten ausprobiert, die auch kritische Sonderzeichen enthielten, und damit keine Fehler bekommen, sondern den gewünschten Erfolg gehabt.

                          Ich habe gerade mysqli_real_escape_string gefunden, in den Beispielen arbeiten sie nur mit handgeschriebenen Queries,

                          Und eben dafür gibt's das da wohl auch noch analog zur gleichnamigen Funktion bei der normalen mysql-Erweiterung - denn man kann ja mit mysqli_query() immer noch auf die "alte" Weise Query-Strings direkt an MySQL übergeben.

                          aber nicht mit prepared statements. Eigentlich dürfte es so ja keinen Grund mehr für Maskierung geben...

                          Nö, gibt's dann auch nicht mehr, wenn man die Query ordentlich "prepared".
                          Um die eventuelle Maskierung kümmert sich bind_param() also ebenso, je nach angegebenem Typ des Parameters, wie darum, ob im letztendlich erzeugten Query-String dann Hochkommata drumherum müssen oder nicht.
                          (Ich habe nur noch nicht ausprobiert, was passiert, wenn man den Typ _nicht_ korrekt angibt - also beim Parameter-binden beispielsweise 'i' angibt, und dann aber doch einen alphanummerischen String übergibt ...)

                          Aber auf jeden Fall gefällt mit an mysqli, dass man das auch als Objekt nutzen kann.

                          gruß,
                          wahsaga

                          --
                          /voodoo.css:
                          #GeorgeWBush { position:absolute; bottom:-6ft; }
                    2. echo $begrüßung;

                      Wenn ich bei der Implementierung davon ausgehe, dass ich diesen Backtick nutzen kann lande ich bei einer Anwendung deren Portierung auf eine andere Datenbank extrem aufwändig ist.

                      Meine Meinung als Datenbanklaie und programmiertechnischer Autodidakt ist, dass man im Hinblick auf Portierbarkeit jede Menge Abstriche machen muss. Um mal ein Beispiel zu nennen: Sequenzen scheiden ebenso aus wie auto_increment, weil das eine oder das andere Feature in dem einen oder anderen DBMS nicht zur Verfügung steht. Ebenso muss man sich bei der Benennung von Bezeichnern stark in Acht nehmen, dass man keinen erwischt, der in dem einen DBMS zwar verfügbar ist, in dem anderen aber reserviert ist. Je portierbarer die Anwendung werden soll desto allgemeiner muss man bleiben. Die Anwendung ist dann also wunderbar portierbar läuft aber möglicherweise auf jedem System nur auf Sparflamme. Alternativ kann auch die Datenbankabstraktionsschicht ein in einem der unterstützten DBMSe nicht vorhandenes Feature anderweitig nachbilden.

                      Ich ziehe aus diesem Grund mittlerweile die Methode mit den Parametern von Statements bei JDBC oder ADO vor, da hier der entsprechende Treiber die Erkennung der entsprechenden Typeigenheiten übernimmt. Aber gerade bei PHP dürfte es (ok, ich hab mich nicht ganz tief eingearbeitet...) Gang und Gebe sein, die Statements im Skript und nicht einem (austauschbaren) Datenbankobjekt zu lagern, so dass alle von Hand nachgezogen werden müssen.

                      Ja, das sieht so aus, weil wohl die meisten PHP-Anwender wenig Programmiererfahrung mitbringen und einfach so drauflos programmieren, wie es in der Anfängerliteratur gelehrt wird. Mehr Möglichkeiten als das gab es ja bisher (vor PHP 5) auch nicht - Datenbankabstraktionsschichten von Dritthersteller mal ausgenommen (PEAR zähle ich auch dazu) und mit MySQL-API-verblendeten Augen geschaut. Seit PHP 5 gibt es, wie wahsaga schon erwähnte, mysqli und seit PHP 5.1 steht PDO innerhalb PHPs zur Verfügung. PDO ist eine Datenbankabstraktionsschicht für so gut wie alle Datenbank-APIs die in PHP enthalten sind. PDO bietet aber "nur" eine einheitliche Programmierschnittstelle. (Statements mit Platzhaltern und automatischer Quotierung sind auch dabei.) Mann kann damit natürlich immer noch Querys absenden, die datenbankspezifisch sind, was ggf. einer Portierbarkeit im Weg steht.

                      Ich sehe ja durchaus den Vorteil, ich kenne Leute die Vergeben Tabellennamen mit Leerzeichen, da kommt man um sowas gar nicht umher, aber bei Access nach xyz müsste ich trotzdem [ ] durch irgendwas anderes ersetzen - sehr teuer. Ich ziehe es deshalb vor die Modelle so aufzubauen, dass eine derartige Syntax nicht erforderlich ist.

                      Datenbankabstraktionsschichten bringen schon mal einige Vorteile. Wenn man die Querys auch noch von einem Querybuilder zusammenbauen lässt, der Feldnamen, Tabellennamen, Werte usw. übergeben bekommt und mit einer datenbankkonformen Quotierung und Maskierung versieht, ist man auch schon mal einen Schritt weiter. Aber auch hier bleibt der Nachteil bestehen, dass man nur standardkonforme Abfragen verwenden kann, um portierbar zu bleiben.

                      Mittlerweile bin ich dazu übergegangen der Anwendungslogik nur noch eine Datenschnittstelle (man beachte das nicht vorhandene "bank") bereitzustellen. Von Querys und anderen datenbanktechnischen Details bekommt sie nichts mehr mit. Über die Schnittstelle werden nur einzelne Werte/Parameter oder Daten-Arrays/Objekte übergeben. Ja, es ist damit noch nicht einmal erforderlich, dass Datenquelle und -senke ein DBMS ist.

                      Innerhalb dieser Datenschicht kann ich alle Features nutzen, die mir die Datenbank so bietet. Die Querys können komplett vorhanden sein oder auch in die einzelnen Klauseln zerlegt vorbereitet sein, damit man beispielsweise auch mal der WHERE-Klausel flexibel Bedingungen hinzufügen kann. (PEARs DB_Table diente mir als Ideengeber.)

                      Eine spätere Portierung ist damit zwar nicht durch einfaches Austauschen der darunter liegenden Datenbankabstraktion bzw. durch Ansprechen eines anderen Treibers dieser DBA erledigt, doch das ist der Kompromiss, den ich an der Stelle eingehe, um die Fähigkeiten des DBMS bestmöglich nutzen zu können. Falls ich also mal portieren möchte, muss ich diese Datenschichtdateien anpassen, kann dann aber auch gleich wieder alle Features des neuen DBMS verwenden.

                      echo "$verabschiedung $name";