DB-Einträge mit Einträgen aus ASCII-Datei vergleichen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • DB-Einträge mit Einträgen aus ASCII-Datei vergleichen

    Ich habe hier ein seltsames Phänomen, das ich mir nicht erklären kann.
    Vielleicht hat einer von euch eine Idee:

    Ich habe eine Reihe von Einträgen (so knapp 10.000) in einer Mysql-Tabelle.
    Diese werden täglich mit Einträgen aus einer ASCII-Datei verglichen.

    Ist dieser Eintrag sowohl in der DB wie auch in der ASCII-Datei vorhanden, passiert nix.
    Ist der Eintrag nur in der ASCII-Datei vorhanden, passiert nix.
    Ist der Eintrag in der DB vorhanden, nicht aber in der ASCII-Datei, wir ein Flag gesetzt (char Feld von 1 auf 0)

    Etwas vereinfacht dargestellt, aber so läuft's im Großen und Ganzen ab.

    Zur Vorgehensweise:
    Ich lese die Einträge aus der DB aus und speichere sie in einem Array.
    Dann lese ich die ASCII-Datei Zeile für Zeile aus und vergleiche jeden Eintrag mit dem DB-Array (in_array()).

    Das Ganze funktioniert auch soweit, ausser, dass ab und zu Einträge ignoriert werden, d.h. der Eintrag existiert z.B. in der DB, nicht aber in der ASCII-Datei und trotzdem bleibt das Flag auf 1 und wird nicht auf 0 gesetzt.
    Das ändert sich auch nicht, wenn ich das Programm mehrfach ausführe. Diese Einträge werden immer ignoriert.

    Es ist mir ein Rätsel warum, und warum dann auch konsequent immer die Gleichen. Diese Einträge unterscheiden sich nicht von den anderen, die korrekt abgearbeitet werden.

    Vielleicht hat jemand dazu eine Idee.
    heute bug ich, morgen browse ich...

  • #2
    Hallo,

    Zitat von frezno Beitrag anzeigen
    Diese Einträge unterscheiden sich nicht von den anderen, die korrekt abgearbeitet werden.
    auch nicht durch Sonderzeichen oder Umlaute?

    Edit: oder durch unterschiedliche Zeilenumbrüche (CRLF statt LF), Leerzeichen am Zeilenende oder Groß-/Kleinschreibung?

    Gruß,

    Amica
    Zuletzt geändert von AmicaNoctis; 08.10.2009, 11:51.
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

    Kommentar


    • #3
      nein, alles identisch.
      Die Einträge sind reine Zahlenfelder, wie z.B. 12345-123-123

      Aber auch wenn, dürfte es einen anderen Grund haben, denn die Einträge werden ja auch nicht korrekt geflaggt, wenn sie nicht in der ASCII-Datei vorhanden sind.
      Und da ist die Prüfung ja eigentlich einfach: Eintrag in DB vorhanden, in ASCII-Datei nicht, also setzte Flag von 1 auf 0

      Wenn jedoch beide Einträge vorhanden wären, nur (z.B. durch Sonderzeichen oder was auch immer) unterschiedlich interpretiert werden würden, wäre das Ergebnis ja auch wieder: Eintrag nicht vorhanden (da unterschiedlich), also Flag ändern.
      heute bug ich, morgen browse ich...

      Kommentar


      • #4
        Achso, laut deiner Aussage im ersten Post liest du die DB ein, vergleichst dann aber nur die Zeilen aus der Datei mit dem DB-Array. Es passiert aber kein umgekehrter Vergleich, d. h. du merkst zwar, wenn eine Dateizeile nicht in der DB ist, aber nicht, wenn ein Datensatz nicht in der Datei ist, also wird das Flag nie gelöscht, kann das sein?

        Edit: übrigens kommst du in jedem Fall schneller, wenn du die Datei (ist ja auch nur ein einspaltiger CSV) in eine DB-Tabelle lädst und einen UPDATE ... LEFT JOIN drüberlaufen lässt, der das Flag setzt/löscht.
        Zuletzt geändert von AmicaNoctis; 08.10.2009, 12:25.
        [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
        Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
        Super, danke!
        [/COLOR]

        Kommentar


        • #5
          Zitat von AmicaNoctis Beitrag anzeigen
          Es passiert aber kein umgekehrter Vergleich, d. h. du merkst zwar, wenn eine Dateizeile nicht in der DB ist, aber nicht, wenn ein Datensatz nicht in der Datei ist,
          wenn du damit meinst, dass in der ASCII-Datei Einträge sein können, die nicht in der DB stehen und das dann natürlich nicht erkann wird, dann stimmt das. Das ist allerdings auch nicht relevant, da ich die dann nicht brauche.

          Kurz eine genauere Erklärung:
          Die ASCII-Datei (2 spaltig, kommagetrennt) ist eine Artikelliste aus einer Datenbank (alle Artikel)
          Mit dieser Liste gleiche ich die Einträge einer anderen DB ab. Die Einträge dort umfassen jedoch nicht alle Einträge aus der ASCII-Liste, sondern nur einen Teil.
          Deshalb prüfe ich auch nicht darauf, ob Einträge aus der ASCII-Liste nicht in der DB existieren.

          also wird das Flag nie gelöscht, kann das sein?
          nein, denn normalerweise klappt es ja, nur in einigen Ausnahmefällen nicht.

          Edit: übrigens kommst du in jedem Fall schneller, wenn du die Datei (ist ja auch nur ein einspaltiger CSV) in eine DB-Tabelle lädst und einen UPDATE ... LEFT JOIN drüberlaufen lässt, der das Flag setzt/löscht.
          hmmm, interessanter Gedanke
          muss ich mal ausprobieren. Zeit spielt zwar keine wirkliche Rolle in dem Fall, aber es mag die bessere und vielleicht auch exaktere Vorgehensweise sein.
          heute bug ich, morgen browse ich...

          Kommentar


          • #6
            Zitat von frezno Beitrag anzeigen
            wenn du damit meinst, dass in der ASCII-Datei Einträge sein können, die nicht in der DB stehen und das dann natürlich nicht erkann wird, dann stimmt das.
            Nein, genau anders herum, das ist ja das Problem. Wenn in dem Array die DB-Daten stehen und du die Datei mit in_array vergleichst, bekommst du doch gar nicht mit, dass in der Datei was fehlt. Du müsstest andersrum vergleichen, also das Array durchgehen und jeden Eintrag in der Datei suchen, dann findest du auch die fehlenden. Aber wie gesagt, das ist ohnehin höchst unperformant.

            Zitat von frezno Beitrag anzeigen
            nein, denn normalerweise klappt es ja, nur in einigen Ausnahmefällen nicht.
            Das kann ich nicht nachvollziehen, wenn du nicht deine Vorgehensweise verkehrt beschrieben hast.
            Zuletzt geändert von AmicaNoctis; 08.10.2009, 14:17.
            [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
            Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
            Super, danke!
            [/COLOR]

            Kommentar


            • #7
              Hier mal der relevante Code.
              Vielleicht sehe ich bloss den Wald vor Bäumen nicht und ich hab wirklich einen Gedankenfehler drin.

              PHP-Code:
              //-----------------------------------------------------------------------------
              //-- Jetzt muss geprüft werden, ob Artikel in der Datenbank enthalten sind,
              //-- diese aber nicht mehr in der Liste stehen.
              echo "Artikel werden gepr&uuml;ft, die noch in der Datenbank stehen, aber nicht mehr in der Liste.<br />";

              //-- Datenzeiger erst mal wieder auf den Anfang stellen.
              rewind($fh);

              //-- Alle Artikelnummern aus der Liste einlesen und in ein Array speichern.
              while (!feof($fh))
              {
                  
              //-- Liste zeilenweise einlesen
                  
              $buffer fgets($fh1024);

                  
              //-- Zeile in Artikelnummer und Stückzahl aufteilen
                  //-- Das Ergebnis ist dann:
                  //-- data[0] = Artikelnummer
                  //-- data[1] = Stückzahl
                  
              $data explode(','$buffer);

                  
              //-- Artikelnummern in das Array data2 speichern.
                  
              $data2[] = $data[0];
              }

              //-- Jetzt werden alle Artikel abgefragt.
              $sql "SELECT p_oem_sku
                           , p_qty
                           , p_visible
                        FROM products
                       WHERE manufacturer = 8
                         AND p_oem_sku <> 0"
              ;

              $result mysql_query($sql);

              while (
              $r mysql_fetch_array($result))
              {
                  
              //-- Wurde eine Artikelnummern gefunden, die nicht in der Liste steht
                  //-- und ist qty gleich 0, dann wird das Visible-Flag auf 0 gesetzt,
                  //-- falls es auf 1 steht.
                  
              if ((! in_array($r['p_oem_sku'], $data2)) && ($r['p_qty'] == 0) && ($r['p_visible'] == 1))
                  {
                      
              $sql_u "UPDATE products
                                   SET p_visible = '0'
                                     , p_modified = NOW()
                                 WHERE p_oem_sku = '"
              trim($r['p_oem_sku']) ."'";

                      
              $res mysql_query($sql_u);

                      echo 
              $r['p_oem_sku'] ." in Liste nicht enthalten, QTY = 0, Visible von 1 auf 0 gesetzt.<br />";
                  }

                  
              //-- Wurde eine Artikelnummern gefunden, die nicht in der Liste steht
                  //-- und ist qty gleich 1, dann wird das Visible-Flag auf 1 gesetzt,
                  //-- falls es auf 0 steht.
                  
              if ((! in_array($r['p_oem_sku'], $data2)) && ($r['p_qty'] == 1) && ($r['p_visible'] == 0))
                  {
                      
              $sql_u "UPDATE products
                                   SET p_visible = '1'
                                     , p_modified = NOW()
                                 WHERE p_oem_sku = '"
              trim($r['p_oem_sku']) ."'";

                      
              $res mysql_query($sql_u);

                      echo 
              $r['p_oem_sku'] ." in Liste nicht enthalten, QTY = 1, Visible auf 1 gesetzt.<br />";
                  }
              }

              fclose($fh); 
              heute bug ich, morgen browse ich...

              Kommentar


              • #8
                Ok, also gehst du beim Vergleich doch die DB-Tabelle durch und nicht die Datei. Dann hast du es aber falsch beschrieben. Ich hatte extra mehrmals nachgefragt.

                Mögliche Fehlerursache:
                Du benutzt beim Update trim. Wenn es denn sein könnte, dass in der DB Leerzeichen enthalten sind, die da nicht sein sollen, musst du auch beim in_array trim benutzen.
                [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                Super, danke!
                [/COLOR]

                Kommentar

                Lädt...
                X