HP-User: Hab ich was übersehen?

Abend Forum

Für mein kleines Projekt hab ich nach Möglichkeiten gesucht, den Überblick über verschiedene Geschäftsvorfälle mittels eines geeigneten Programms zu behalten. Was soll ich sagen - es ist wie immer: Wenn du willst, dass was 100%ig zu deinem Vorhaben passt, musst du es...

A)
...machen lassen (langweilig!)

B)
...selber machen (fein!)

Hierzu hab ich mal was vorbereitet *g*

Beschreibung steht hinten in klein dran. Ich zähle aktuell 15 Wertepaare.
Ich frage mich in einem ersten Schritt, ob ich noch was vergessen habe.

Programmziel soll sein, dass ich den Überblick über diese Werte behalte. Prinzipiell soll nach jedem Wert gesucht werden können. Und jeder Wert soll editierbar sein. Probleme die ich jetzt schon sehe:

Nr.1)
Ändere ich den "Status", muss "Status-Datum" automatisch auf "heute" gesetzt werden und auch "Status-Datum-Ablauf" muss sich dann anpassen.

Nr.2)
Sucht man zum Beispiel nach "Kd.-Nummer", und hat der Kunde mehrere Geschichten gebucht, gibt es logischerweise auch mehrere Treffer. Da muss ich dann irgendwie eine Liste bauen, aus der ich dann den entsprechenden Datensatz herauspicke.

Datensatzschlüssel brauch ich wohl keine, da die KG-Nr ja einzigartig ist.

Was auch noch "nice to have" wäre, ein Datum, dass das Erfassungsdatum des Kunden enthält. Dann wüsste man, wie lange einer schon Kunde ist. Z. B. ein Feld "Kd-Datum".

Da es eie Einzelplatzversion wird, brauch ich mir keinen Kopf über "Race-Conditions" machen.

Also, fehlt was ? Irgendwelche Gedankengänge?
Bisher hab ich alles mit csv.-Dateien gelöst. Ich glaube aber, dass es langsam Zeit wird, mal so ein DB-Konstrukt zu bauen (MySQL o. ä.).
Die Such und Ersetzfunktion soll ja bei einer DB einfacher gehen...

Gruss HP-User

  1. Einfach eine Datenbank nehmen, MYSQL zB eine Tabelle mit den Werten anlegen und dann eine Oberfläche drum herum basteln in welcher Sprache auch immer.

    dann kannst du einfach eine Query machen und das Ergebnis formatiert ausgeben oder über Update alle gewollten Änderungen vornehmen.

    1. Hi ms88

      Einfach eine Datenbank nehmen, MYSQL zB eine Tabelle mit den Werten anlegen und dann eine Oberfläche drum herum basteln in welcher Sprache auch immer.

      Ja, das war auch meine Idee dies mittels Datenbank zu lösen. Werd Perl nehmen *g*

      dann kannst du einfach eine Query machen und das Ergebnis formatiert ausgeben oder über Update alle gewollten Änderungen vornehmen.

      Hehe, ob das so einfach wird, wird sich zeigen. Danke ms88.

      Gruss HP-User

  2. Ich glaube aber, dass es langsam Zeit wird, mal so ein DB-Konstrukt zu bauen

    Told you so.

    ob ich noch was vergessen habe

    Datentypen.

    Ändere ich den "Status", muss "Status-Datum" automatisch auf "heute" gesetzt werden und auch "Status-Datum-Ablauf" muss sich dann anpassen.
    Status-Datum          20120908    Das Datum, an dem der Eintrag bei Status geändert wurde
    Status-Datum-Ablauf   20130908    Datum von „Status-Datum“ plus ein Jahr

    Das ist Murks, weil die Daten inkonsistent werden können. Man speichert keine Daten, die aus vorhandenen Daten abgeleitet/berechnet werden. Entferne Status-Datum-Ablauf aus dem Modell und füge es als View hinzu, oder verschiebe die +1-Jahr-Logik in den Programmcode.

    gibt es logischerweise auch mehrere Treffer. Da muss ich dann irgendwie eine Liste bauen

    Das macht schon die Datenbankschnittstelle.

    Datensatzschlüssel brauch ich wohl keine, da die KG-Nr ja einzigartig ist.

    ?? Die KG-Nr *ist* der Schlüssel.

    Status    F   F=frei / B=belegt / G=gebucht aber noch nicht geschaltet / wg. Zahlungseingang
    Kd-Konto  0   Wert „0“ = Kurzgeschichte noch frei, oder belegt und bezahlt / Wert „negativ“ = Kurzgeschichte gebucht, aber noch nicht bezahlt

    Das ist Murks. Verwende statt seltsamer Abkürzungen eine Aufzählung aussagekräftiger Werte.

    1. Hi CPAN

      Told you so.

      Yes, your 're right.

      ob ich noch was vergessen habe

      Datentypen.

      ? Ich dachte das macht man heute nicht mehr. Alle Daten als Text! Auch Feldlängen sind doch heutzutage out!?
      Perl kann eine "1" als Zahl lesen, auch wenn es eine Text "1" sein sollte?

      Das ist Murks, weil die Daten inkonsistent werden können. Man speichert keine Daten, die aus vorhandenen Daten abgeleitet/berechnet werden. Entferne Status-Datum-Ablauf aus dem Modell und füge es als View hinzu, oder verschiebe die +1-Jahr-Logik in den Programmcode.

      Du meinst, dass bei der Ausgabemaske das "Status-Datum-Ablauf" vom "Status-Datum" berechnet und angezeigt wird? Dann wär der Wert aber nicht in der Tabelle gespeichert. Wenn ich jetzt checken möchte, ob es schon drei Monate vor Ablauf ist, hab ich dann nicht mehr arbeit?

      Status    F   F=frei / B=belegt / G=gebucht aber noch nicht geschaltet / wg. Zahlungseingang
      Kd-Konto  0   Wert „0“ = Kurzgeschichte noch frei, oder belegt und bezahlt / Wert „negativ“ = Kurzgeschichte gebucht, aber noch nicht bezahlt

      Das ist Murks. Verwende statt seltsamer Abkürzungen eine Aufzählung aussagekräftiger Werte.

      Der Link sagt mir nichts. Hier ging es darum, sichtbar zu machen, ob die Gebuchte Fläche bereits bezahlt ist , oder nicht. Sagen wir mal die Flache kostet zum Beispiel 111,00 €, dann würde dort wenn der Kunde bucht, -111,00 € stehen. Geht auf dem Konto die Zahlung ein, steht auf dem Kontoauszug bei Verwendungszweck "KG001J" und ich geh in das Programm und stell den Wert -111,00 € auf Null. Jetzt weis man es ist bezahlt. Gleichzeitig stelle ich den "Status" von "G" auf "B". Damit ändern sich dann auch die Datumsfelder "Status-Datum" auf den Änderungstag, "Status-Datum-Ablauf" plus 1 Jahr.

      So dachte ich mir das als kleines Kontrollprogramm, damit man weiss, was mit dem Datensatz ist.

      Gruss HP-User

      1. Datentypen.

        ? Ich dachte das macht man heute nicht mehr.

        Natürlich macht man das. In Umgebungen wie Programmiersprachen oder Datenbanken, die Typisierung zur Verfügung stellen, wäre es töricht, sie nicht zu benutzen. Obwohl mir deine Geschäftsprozesse und -logik noch weitgehend schleierhaft sind (da musst du noch viel erklären), wage ich mich mal an ein Schema:

        drop table if exists "Kurzgeschichten";  
        drop table if exists "Kunden";  
        drop type if exists enum_status;  
        drop sequence if exists seq_kunden_id;  
        drop extension if exists "uuid-ossp";  
          
        create extension "uuid-ossp";  
        create sequence seq_kunden_id start with 100100;  
        create type enum_status as enum ('frei', 'belegt', 'gebucht');  
        create table "Kunden" (  
            "Id"                bigint not null primary key default nextval('seq_kunden_id'),  
            "Beitritt"          date not null default current_date(),  
            "Firma"             text,  
            "Straße"            text not null,  
            "Hausnummer"        text not null,  
            "Ort"               text not null,  
            "PLZ"               text not null,  
            "Ansprechpartner"   text not null,  
            "Telefon"           text,  
            "Fax"               text,  
            "Email"             text not null  
        );  
        create table "Kurzgeschichten" (  
            "Id"        uuid not null primary key default uuid_generate_v4(),  
            "Titel"     text not null,  
            "Status"    enum_status not null default 'frei',  
            "geändert"  date not null default current_date(),  
            "Kunden_Id" bigint references "Kunden" ("Id"),  
            "Konto"     money not null default 0  
        );  
        
        

        Ich sag's gleich: pauschale Antworten wie "sagt mir nichts" und "für mich […] nicht mehr lesbar", mit denen du deine Ignoranz abschirmst, will ich nicht mehr hören. Bemühe dich im Sinne von SELF, dir neue Inhalte zu erschließen und gezielt Fragen zum Verständnis zu stellen, statt die mühsam aufgeschriebene Expertise zu verneinen/-geuden.

        Auch Feldlängen sind doch heutzutage out!?

        Ich weiß nicht, was diese Frage soll. Speicher ist endlich. Eine Obergrenze gibt's immer, wenn auch nicht explizit.

        Du meinst, dass bei der Ausgabemaske das "Status-Datum-Ablauf" vom "Status-Datum" berechnet und angezeigt wird?

        Ja.

        Dann wär der Wert aber nicht in der Tabelle gespeichert.

        Das soll so sein.

        Wenn ich jetzt checken möchte, ob es schon drei Monate vor Ablauf ist, hab ich dann nicht mehr arbeit?

        Mehr Arbeit macht sich nur der Artisan, der seine Werkzeuge nicht gut handhabt.

        select "Id", "Titel" from "Kurzgeschichten" where "geändert" + interval '1 year' - interval '3 months' < current_date();

        damit man weiss, was mit dem Datensatz ist.

        use utf8;  
        use DBIx::Class::Schema::Loader qw();  
        DBIx::Class::Schema::Loader->loader_options(  
            naming        => {ALL => 'preserve'},  
            preserve_case => 1,  
        );  
          
        our $schema          = DBIx::Class::Schema::Loader->connect;  
        our $kunden          = $schema->resultset('Kunden');  
        our $kurzgeschichten = $schema->resultset('Kurzgeschichten');  
          
        my $mustermann = $kunden->create({  
            Ansprechpartner => 'Max Mustermann',  
            Email           => 'info@musterworx.example.com',  
            Telefon         => '01234 / 123456',  
            Firma           => 'Musterworx',  
            Straße          => 'Musterstraße',  
            Hausnummer      => 1,  
            PLZ             => 12345,  
            Ort             => 'Musterstadt',  
        });  
        my $zahnputz_lutz = $kurzgeschichten->create({  
            Titel     => 'Der Zahnputz-Lutz',  
            Kunden_Id => $mustermann->Id,  
        });  
          
        my $preis = 110.00;  
        $zahnputz_lutz->update({  
            Status => 'gebucht',  
            Konto  => -$preis,  
        });  
        $zahnputz_lutz->update({  
            Konto    => $zahnputz_lutz->Konto + $preis,  
            Status   => 'belegt', # FIXME was ist mit Teilzahlungen?  
            geändert => 'now()',  
        });  
        
        
        1. Hallo CPAN

          Ich sag's gleich: pauschale Antworten wie "sagt mir nichts" und "für mich […] nicht mehr lesbar", mit denen du deine Ignoranz abschirmst, will ich nicht mehr hören. Bemühe dich im Sinne von SELF, dir neue Inhalte zu erschließen und gezielt Fragen zum Verständnis zu stellen, statt die mühsam aufgeschriebene Expertise zu verneinen/-geuden.

          OK, ich will _versuchen_ ein braver Padawan zu sein.

          Deine Expertise (Perlcode) werd ich mir gleich häppchenweise vornehmen. Aber vorab hab ich noch "allgemeine Fragen" rund um das DB konstrukt:

          1> Ich hatte vor, MySQL zu nehmen. Ist das Installieren kompliziert?
          Behindert es später eine Deportation des Programms auf einen anderen Computer? Perlmodule wären mir sympatischer. Was empfiehlt der Meister?

          3> Wenn das mit meinen Mini-Datensätzen möglich ist, könnte man auch eine CSV-Datenbank machen. Die könnte ich später auch bequem woanders hin einlesen (Charater Separated Values). Auch hier: Was empfiehlt der Meister?

          2> Es gibt Perlmodule, die Datenbankfunktionen übernehmen. Was heisst das eigentlich?

          Wenn CSV Dateien editiert werden, und ich dass zu Fuß mache, ist das umständlich. Nicht nur dass ich mich an die betreffende Zeile mit dem Datensatz "heranlesen" muss, ich muss die Daten Ober- und Unterhalb der zu editierenden Zeile in ein Array stecken, damit sie wieder in der richtigen Reihenfolge in der Datei sind beim Zurückschreiben. Für ein Gästebuch mag das gerade noch gehen, aber für ein Verwaltungsprogramm ist das der Overkill.

          Hab ich jetzt das so richtig verstanden, dass ein DB-Modul einem diese Arbeit abnimmt? Ich sage dem Modul gehe in Spalte X und in Zeile Y und ändere dort den Wert von A zu B. Und um den ganzen kram von der Abwicklung her (Filehandling) muss ich mich nicht weiter kümmern?

          Liegt der Vorteil bei vereinfachten Suchanfragen und Editierbarkeit (ändern der Datensätze)

          Das mal Vorab damit ich weis, welche Form der Tabelle/Daten ich nehmen soll.

          Gruss HP-User

          1. 1> Ich hatte vor, MySQL zu nehmen.

            Von MySQL kann ich nur abraten, es ist ein Desaster.

            ⑴ Das Produkt ist unheilbar zersplittert, das Anzeichen für eine komplett dysfunktionale Community: Oracle, "Community", "Cluster", "Enterprise", Infobright, MariaDB, Drizzle, Percona, OurDelta

            ⑵ Die Lizenz ist außergewöhnlich und schwer zu verstehen. Es erfordert enormen Aufwand, dahinterzusteigen, was die Bedingungen für MySQL unter kommerzieller Nutzung sind und was an den Lizenzgeber abzurichten ist.

            ⑶ Die Software ist katastrophal schlecht und voller Fehler und Ungereimtheiten. Daten werden mutwillig zerstört.

            http://sql-info.de/mysql/gotchas.html
            http://use.perl.org/use.perl.org/_Smylers/journal/34246.html
            http://use.perl.org/use.perl.org/_Ovid/journal/38546.html
            http://use.perl.org/use.perl.org/_Ovid/journal/35786.html
            http://use.perl.org/use.perl.org/_Adrian/journal/32832.html
            http://use.perl.org/use.perl.org/_davorg/journal/38549.html
            http://smylers.hates-software.com/2007/03/20/bdc3ce48.html
            http://ann.hates-software.com/2003/08/27/a34fc9e6.html
            http://hateful.hates-software.com/2006/10/19/f304fb73.html
            http://smylers.hates-software.com/2007/11/02/f0afeb66.html
            http://smylers.hates-software.com/2008/02/12/c0df67ed.html
            http://mzsanford.wordpress.com/2010/12/28/mysql-and-unicode/
            http://blogs.perl.org/users/ovid/2012/09/my-top-mysql-gripes.html
            http://www.shlomifish.org/open-source/anti/mysql/

            ⑷ Die Verantwortlichen hinter dem Projekt legen dermaßen gestörtes Verhalten an den Tag, man mag meinen, diese Individuen seien der Klapsmühle entsprungen: bizarre Meinungen, die Best Practices der Industrie gelten nicht für sie (http://web.archive.org/web/200101270814/http://mysql.com/doc/B/r/Broken_Foreign_KEY.html) nebst 180°-Kehrtwende, nachdem Unterstützung für Fremdschlüssel hinzugekauft wurde; Druck auf EU-Organe, um etablierte Lizenzen zu nullifizieren: http://www.groklaw.net/article.php?story=20091208104422384

            Was empfiehlt der Meister?

            PostgreSQL

            Ist das Installieren kompliziert?

            nein

            Behindert es später eine Deportation des Programms auf einen anderen Computer?

            Das sind zu starke Worte. Sagen wir so, es ist einfach eine Sache mehr, die man machen muss.

            3> Wenn das mit meinen Mini-Datensätzen möglich ist, könnte man auch eine CSV-Datenbank machen. Die könnte ich später auch bequem woanders hin einlesen (Charater Separated Values).

            Davon rate ich ab: nicht ACID-konform.

            2> Es gibt Perlmodule, die Datenbankfunktionen übernehmen. Was heisst das eigentlich?

            Vielmehr ist es so, dass sich die Funktionalität im DBMS befindet. Besagte Perlmodule bieten eine Schnittstelle dorthin.

            Hab ich jetzt das so richtig verstanden, dass ein DB-Modul einem diese Arbeit abnimmt? […] Und um den ganzen kram von der Abwicklung her (Filehandling) muss ich mich nicht weiter kümmern?

            Ja, und noch viel mehr. Ja.

            Liegt der Vorteil bei vereinfachten Suchanfragen und Editierbarkeit (ändern der Datensätze)

            ja

            Das mal Vorab damit ich weis, welche Form der Tabelle/Daten ich nehmen soll.

            Einen Schemavorschlag habe ich schon abgegeben.

            1. Abend CPAN

              Das es um MySQL so schlecht bestellt ist, wusste ich gar nicht. Es ist so verbreitet und über all anzutreffen, dass ich davon ausging es sei das "Beste" überhaupt.

              Ich hab folgende Seite gefunden: Hier.

              Dort heisst es zur Installation von PostgreSQL:

              Datenbankserver

              A)
              PostgreSQL wird durch folgendes Paket installiert [1]:

              ->postgresql

              Dieses Paket installiert die neueste verfügbare Version von PostgreSQL aus den offiziell unterstützten Paketquellen (main).
              Datenbankclient

              B)
              Es ist natürlich nicht notwendig auf einem Client, also auf einem Rechner der nur auf die Datenbank zugreifen möchte, auch die Datenbank installiert zu haben, daher genügt es hier folgendes Paket zu installieren [1]:

              ->postgresql-client

              Dann reicht für eine Einzelplatzversion des zu schreibenden Programms wohl die Version unter "B)"? Ich schnall das nich ganz. Was brauch ich zum Starten. Ziel: Ich möchte "lokal" auf meinem PC eine Datenbank machen, die ich mit Perl bearbeiten, abfragen kann.

              Und hier hab ich ein Schaubild gefunden, wo die SQL-Kommunukation schematisch zeigen(im oberen Viertel.

              Gibt es für PostgreSQL auch ein Modul für Perl, so wie DBI für DBD::Oracle oder DBD::CSV?

              Gruss HP-User

              1. Ich hab folgende Seite gefunden: Hier.

                Die Anleitung schaut für den Einstieg schaut sehr brauchbar aus.

                Dort heisst es zur Installation von PostgreSQL:
                Datenbankserver
                Datenbankclient
                Was brauch ich zum Starten. Ziel: Ich möchte "lokal" auf meinem PC eine Datenbank machen, die ich mit Perl bearbeiten, abfragen kann.

                beides

                Und hier hab ich ein Schaubild gefunden, wo die SQL-Kommunukation schematisch zeigen(im oberen Viertel.

                Es ist ganz gut, einmal DBI für die Grundlagen durchzuarbeiten. Für den Produktiveinsatz empfehle ich die ORM-Erweiterung DBIx::Class, das halbiert glatt die Menge des nötigen Codes und man braucht sich nicht mehr mit SQL rumärgern. Codebeispiel von mir gab es schon threadaufwärts.

                Gibt es für PostgreSQL auch ein Modul für Perl, so wie DBI für DBD::Oracle oder DBD::CSV?

                DBD::Pg, in Ubuntu vorhanden als Package libdbd-pg-perl.

                1. Hallo CPAN

                  Wollte den Thread nicht so in der Luft hängen lassen, deshalb hier ein Abschlussstatement:

                  Nach dem ich wieder und immer wieder versucht habe, postgreSQL zu instalieren, muss ich mich nun geschlagen geben und verwerfe diesen Ansatzt.

                  Zur Begründung:
                  Es lies sich nicht installieren. Es gab zig Fehlermeldungen. Unter anderem ist der Quellpfad von Ubuntupaketen nicht mehr aktuell, bzw. hat sich geändert. Mein Ubuntu ist etwas älter. Ein Update geht nicht mehr (Version 9.04). Und mit Sicherheit spiele ich kein neues OS auf - hier hängt einfach zu viel an dieser Maschine dran!

                  Es gab Sicherheitswarnungen, das postgreSQL den Rechner unsicher macht und ein Risiko darstellt. Allein das Handbuch über die zu machenden Einstellungen, wer, wie, wo im Netz drauf zugreifen darf und nicht, sprengt den Aufwand für eine lokale Datenbank erheblich. Wenn ich da an einen Umzug auf einen neuen Rechner denke, muss ich mir ja ein ganzes Battalion an Computerspeziallisten einkaufen...

                  Ich hab nach einer einfachen Datenbank/Datenbankähnlichen Lösung gesucht.
                  Und wie kann es anders sein - wieder bei CSV gelandet. Nach ähnlichen installationsschwierigkeiten, läuft jetzt endlich das Modul DBD::CSV über BDI. Bis das aufgespielt war - ist wieder eine Story für sich...

                  Abgesehen davon, das ich die Kommunikation mit der Datenbank noch lernen muss, stecke ich schon wieder in Verständnisschwierigkeiten fest:
                  A)
                  Diese Tutorials sind fast alle in englisch - was ich grundsätzlich kann, aber die Sache nicht einfacher macht.

                  B)
                  Deutsche Tutorials sind rar!

                  C)
                  Wenn man mal eines gefunden hat, steht da statt einer vernünftigen Syntaxerklärung so wirres Zeugs wie "foo" und "bar" und "bam". Keine Ahnung was das alles bedeuten soll. Warum kann man kein vernünftiges, deutsches, praxixbezogenes Beispiel machen -  ohne Hieroglyphen?

                  Das geht keinesfalls gegen dich - ich spreche allgemein gegen die im Netz verfügbaren Beispiele.

                  "Foo Bar?" wohl eher "Pfui Bääh!"

                  Gruss HP-User  *gerade in einer schöpferischen Tiefphase*

                  1. Hi,

                    Wenn man mal eines gefunden hat, steht da statt einer vernünftigen Syntaxerklärung so wirres Zeugs wie "foo" und "bar" und "bam". Keine Ahnung was das alles bedeuten soll. Warum kann man kein vernünftiges, deutsches, praxixbezogenes Beispiel machen -  ohne Hieroglyphen?

                    foo/bar sind Leerwörter. Damit soll klar gemacht werden, dass da einfach irgendwelche Variablennamen hinsollen. Siehe z.B. bei Wikipedia.

                    Bis die Tage,
                    Matti

  3. Hallo,

    Hierzu hab ich mal was vorbereitet *g*

    Warum soll eine Fax-Nummer nicht mehr zeitgemäß sein?

    Nr.1)
    Ändere ich den "Status", muss "Status-Datum" automatisch auf "heute" gesetzt werden und auch "Status-Datum-Ablauf" muss sich dann anpassen.

    Wie CPAN schon schrieb: Status-Datum-Ablauf hat in der Tabelle nichts zu suchen. Um Status-Datum zu aktualisieren wirst du wohl Trigger verwenden müssen da die Funktion von TIMESTAMP-Spalten dir hier nicht weiterhilft - oder du setzt das Datum einfach im UPDATE-Query mit dem du den Status änderst.

    Nr.2)
    Sucht man zum Beispiel nach "Kd.-Nummer", und hat der Kunde mehrere Geschichten gebucht, gibt es logischerweise auch mehrere Treffer. Da muss ich dann irgendwie eine Liste bauen, aus der ich dann den entsprechenden Datensatz herauspicke.

    Nein, du musst du Kunden in eine eigene Tabelle verfrachten, sonst würdest du ja zu jeder Kurzgeschichte die kompletten Daten des Kunden speichern (Stichwort Normalisierung). In die Tabelle mit den Kurzgeschichten gehört dann nur noch die Kundennummer mit deren Hilfe du dann den zugehörigen Kunden raussuchen kannst.

    Was auch noch "nice to have" wäre, ein Datum, dass das Erfassungsdatum des Kunden enthält. Dann wüsste man, wie lange einer schon Kunde ist. Z. B. ein Feld "Kd-Datum".

    Wo liegt da das Problem? Füge das Feld doch einfach ein ...

    Gruß,
    Tobias

    1. Hi tk

      Warum soll eine Fax-Nummer nicht mehr zeitgemäß sein?

      Gut ist wieder im Boot.

      Wie CPAN schon schrieb: Status-Datum-Ablauf hat in der Tabelle nichts zu suchen. Um Status-Datum zu aktualisieren wirst du wohl Trigger verwenden müssen da die Funktion von TIMESTAMP-Spalten dir hier nicht weiterhilft - oder du setzt das Datum einfach im UPDATE-Query mit dem du den Status änderst.

      Ich weiss, dass ich nur das "Status-Datum" speichern könnte, und den "Status-Datum-Ablauf" berechnen lassen könnte und dann in der Maske anzeigen lassen könnte. Wäre aber dieser Wert "Status-Datum-Ablauf" in die Datenbank eingeschrieben, könnte ich schneller und einfacher nach auslaufenden Verträgen suchen. (Später in der Such-Engine)

      Nein, du musst du Kunden in eine eigene Tabelle verfrachten, sonst würdest du ja zu jeder Kurzgeschichte die kompletten Daten des Kunden speichern (Stichwort Normalisierung). In die Tabelle mit den Kurzgeschichten gehört dann nur noch die Kundennummer mit deren Hilfe du dann den zugehörigen Kunden raussuchen kannst.

      Ahaaaaa - Also würde mit meiner Methode folgendes eintreten. Hat ein Kunde mehrere Kurzgeschichten gebucht, und änderte sich seine Telefonnummer, müsste ich nach allen gebuchten KG's suchen und bei jedem Datensatz die Telefonnummer manuell ändern. Das wäre unschön! Wäre aber mit einem "Such alle mit KD-Nummer X und ersetze die dortige Kd-Telefon mit y" lösbar. Das programm könnte rückfragen und sagen "Nur in diesem Datensatzt, oder bei allen gefundenen ersetzen. Also prinzipiell auch so möglich.

      Da wir grad in der Datenbank-Rubrik auf Selfhtml sind (zu meinem Verständnis*g*):

      Die DB bekommt einen Ordner: "EZ-KDB"
      Dieser Ordner ist die Datenbank.

      Der Ordner bekommt files: basic-datasheet.?<-
      Hier steckt die Tabelle drin. Das Fragezeichen nach dem Punkt ist die Dateiendung, die je nach verwendeter Speicherengine anders endet.
      "basic-datasheet" ist quasi die Muttertabelle. Aus Ihr lassen sich weitere Tabellen generieren. Z. B. "customer-datasheet". Hier stehen dann unr die Kundenrelevanten Daten? Generier ich dann bei einer Abfrage eine Art temp. Tabelle "customer-datasheet.tmp", die das Suchergebin enthält? Und die lösch ich nacher wieder? Oder wie hast du das mit der extra Kundentabelle gemeint?

      Sorry die dumme Fragerei.Wie gesagt - MySQL Neuling.

      Wo liegt da das Problem? Füge das Feld doch einfach ein ...

      Ist gemacht :-)

      Gruss HP-User

      1. Hallo,

        Ich weiss, dass ich nur das "Status-Datum" speichern könnte, und den "Status-Datum-Ablauf" berechnen lassen könnte und dann in der Maske anzeigen lassen könnte. Wäre aber dieser Wert "Status-Datum-Ablauf" in die Datenbank eingeschrieben, könnte ich schneller und einfacher nach auslaufenden Verträgen suchen. (Später in der Such-Engine)

        Das geht auch ohne dass der Wert extra in der Datenbank gespeichert ist. Du suchst einfach alle Datensätze die die Bedingung »Status-Datum + 1 Jahr < NOW()« erfüllen (das Heraussuchen der passenden Funktion für das +1 Jahr überlasse ich dir). btw: ein Minus solltest du in den Spaltennamen nicht verwenden, du müsstest sonst Spalten immer maskieren da das Minus sonst als Operator verstanden würde.

        Ahaaaaa - Also würde mit meiner Methode folgendes eintreten. Hat ein Kunde mehrere Kurzgeschichten gebucht, und änderte sich seine Telefonnummer, müsste ich nach allen gebuchten KG's suchen und bei jedem Datensatz die Telefonnummer manuell ändern. Das wäre unschön! Wäre aber mit einem "Such alle mit KD-Nummer X und ersetze die dortige Kd-Telefon mit y" lösbar.

        Wäre, aber sinnvoll wäre das nicht und außerdem würde es die Datenbank nur unnötig aufblähen.

        Da wir grad in der Datenbank-Rubrik auf Selfhtml sind (zu meinem Verständnis*g*):

        Die DB bekommt einen Ordner: "EZ-KDB"
        Dieser Ordner ist die Datenbank.

        Der Ordner bekommt files: basic-datasheet.?<-
        Hier steckt die Tabelle drin. Das Fragezeichen nach dem Punkt ist die Dateiendung, die je nach verwendeter Speicherengine anders endet.

        Jein. Du erstellst in MySQL eine Datenbank und legst darin die benötigten Tabellen an - darum wie das ganze dann auf der Festplatte liegt brauchst du dich nicht kümmern, das macht MySQL selbst. Aber so ganz falsch liegst du nicht, MySQL legt für jede Datenbank ein Verzeichnis an und darin für jede Tabelle drei Dateien (das variiert afaik, da bin ich mir jetzt nicht ganz sicher).

        "basic-datasheet" ist quasi die Muttertabelle. Aus Ihr lassen sich weitere Tabellen generieren.

        Nein. Jede Tabelle ist erstmal "gleichberechtigt". Es mag sein dass sich viele andere Tabellen auf eine Tabelle beziehen (also auf Datensätze darauf verweisen) aber prinzipiell sind sie voneinander unabhängig (so Sachen wie Fremdschlüssel seien jetzt mal außen vor gelassen).

        Generier ich dann bei einer Abfrage eine Art temp. Tabelle "customer-datasheet.tmp", die das Suchergebin enthält?

        Nein. Eine Abfrage von Daten wird per Perl (in deinem Fall, andere Programmiersprachen gehen natürlich auch) an MySQL geschickt, MySQL schickt dann als Antwort die Daten an Perl welches die Daten dann verarbeitet (z.B. anzeigt).

        Sorry die dumme Fragerei.Wie gesagt - MySQL Neuling.

        Dann solltest du dich erstmal in das grundsätzliche Prinzip von MySQL bzw. Datenbanken allgemein einlesen - das hier jetzt alles zu erklären würde zu weit führen.

        Gruß,
        Tobias

  4. Also, fehlt was ? Irgendwelche Gedankengänge?

    Ja.
    Neben profanen Dingen, wie Ort fehlen viel wichtigere Dinge, wie dem Gedankengang, wie und wo die DB erweiterbar sein muß. Das geht dann auch gleichzeitig in das Thema Normalisierung über.

    Heinz

    1. Hi Heinz

      Ja.
      Neben profanen Dingen, wie Ort fehlen viel wichtigere Dinge, wie dem Gedankengang, wie und wo die DB erweiterbar sein muß. Das geht dann auch gleichzeitig in das Thema Normalisierung über.

      Ort ist hinzugefügt. Kd-Datum ist hinzugefügt.
      Update

      Zur Normalisierung sag ich unten, bei tk noch was.

      Gruss HP-User

      1. Hi Heinz

        Ja.
        Neben profanen Dingen, wie Ort fehlen viel wichtigere Dinge, wie dem Gedankengang, wie und wo die DB erweiterbar sein muß. Das geht dann auch gleichzeitig in das Thema Normalisierung über.

        Ort ist hinzugefügt. Kd-Datum ist hinzugefügt.
        Update

        Hm. Dammit könnten wir uns jetzt dran halten. Was ist mit Mobilfunknummer? Was, wenn einer mehrere Nummern hat?
        Was, wenn Du unter einem Kunden verschiedene Konditionen verwalten willst? Ist es für Dich interessant, wann der erste Kundenkontakt hergestellt wurde? usw., usw.

        Zur Normalisierung sag ich unten, bei tk noch was.

        Normalisierung ist wichtig und macht sogar Spaß, wenn man es kann. Aber auch hier muß man für sich selber entscheiden, was wie wichtig ist.
        Theoretisch könnte man auch die Kundendaten normalisieren. Kunde hat eine ID oder Kundennummer, der Rest könnte über eine Tabelle Kundendaten der ID oder Kundennummer zugeordnet werden. Macht hier wenig Sinn, aber verdeutlicht Dir, was Normalisierung erreicht. Dem einen Kunden wird nur Strasse, Ort, Tel zugeordnet, dem nächsten werden 3 Telnummern, 2 Strassen, 2 Orte usw. zugeordnet.

        Dann solltest Du Dir noch Gedanken darüber machen, welche Daten, wenn sie dynamisch zugeordnet werden, irgendwann problematisch werden könnten, weil sie änderbar sind. Diese mußt Du dann doch ggf. redundant führen oder für diesen Fall Deine DB um eine weitere Tabelle erweitern, die diese Redundanz dann beinhaltet. Beispiel, eine Kundenadresse ändert sich. Dann  ist die Frage, ob es für Dich interessant ist, dass er schon Kurzgeschichten unter der alten Adresse geliehen hat, denn dynamisch Daten einsetzen hieße sonst, Historiendaten verfälschen.

        Ist alles lösbar, aber die Grundgedanken zu solchen Themen stehen optimalerweise vor Projektbeginn im großen und Ganzen schonmal.

        Heinz

        1. Abend Heinz

          Ist es für Dich interessant, wann der erste Kundenkontakt hergestellt wurde? usw., usw.

          Ja, der erste Kontakt ist ja auch in der Tabelle.

          Normalisierung ist wichtig und macht sogar Spaß, wenn man es kann [...] Dem einen Kunden wird nur Strasse, Ort, Tel zugeordnet, dem nächsten werden 3 Telnummern, 2 Strassen, 2 Orte usw. zugeordnet.

          Gut zu wissen. Aber wir wollen das Einsteigerprojekt ja nicht "überpowern" ;-)

          Beispiel, eine Kundenadresse ändert sich. Dann  ist die Frage, ob es für Dich interessant ist, dass er schon Kurzgeschichten unter der alten Adresse geliehen hat, denn dynamisch Daten einsetzen hieße sonst, Historiendaten verfälschen.

          Ja, das hab ich mir auch schon gedacht. Wenn ein Kunde , der schon länger Kunde ist, die Adresse ändert, muss ich, oder später eben die Büroangestellte daran denken, unter KD-Datum den alten Wert einzutragen. Sollte ich bei der Arbeit aus der Logik ergeben.

          Ist alles lösbar, aber die Grundgedanken zu solchen Themen stehen optimalerweise vor Projektbeginn im großen und Ganzen schonmal.

          Ja, und diese Grundgedanken sind noch nicht ganz fertig g. Erschwerend kommt hinzu, dass ich diesmal aus rechtlichen Gründen Perl nicht so nutzen kann, wie ich es gewohnt bin. Nämlich auf dem Server und via Browser die Ein- und Ausgabe fahren. Ich nutze hier erstmals Perl "lokal" auf einem Ubuntu-System, und die Ein- und Ausgabe erfolgt über das Terminal (Konsole-Fenster).

          Hier seht ihr einen vorsichtigen Anfang, der nach meinem Geschmack mal wieder zu viele "goto"-Befehle hat. Die Menüs lassen sich alle anwählen. Die "Zurück"-Funktion geht auch überall. Nur "sämtliche" Funktionen gehen natürlich noch nicht. Da ringe ich noch, ob MySQL, CSV "nackt" oder CSV via Modul DBD::CSV. Über die Datenstruktur hab ich mir noch keinen Kopf gemacht. Hier der Programm-Test-Code "Für Konsolenausführung":

          
          #!/usr/bin/perl
          
          use strict;
          use warnings;
          
          my $decider;
          
          ###################################################################
          HauptMenu:
          ###################################################################
          system("clear");
          print "+-----------------------------------------------------+ \n";
          print "| Einschlafzeit / Daten-Verwaltungs-Programm (EZ-DVP) | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print ">> Hauptmenü << \n";
          print " \n";
          print "+-----------------------------------------------------+ \n";
          print "| [1] Kunden anlegen...                               | \n";
          print "|                                                     | \n";
          print "| [2] Kunden suchen...                                | \n";
          print "|                                                     | \n";
          print "| [3] Kurzgeschichte anlegen...                       | \n";
          print "|                                                     | \n";
          print "| [4] Kurzgeschichte suchen...                        | \n";
          print "|                                                     | \n";
          print "| [5] Buchungsstatus abfragen...                      | \n";
          print "|                                                     | \n";
          print "| [6] Statistik aufrufen...                           | \n";
          print "|                                                     | \n";
          print "| [7] Programm beenden...                             | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print "Bitte Auftrag auswählen (1-7):";
          $decider = <STDIN>;
          chop($decider);
          if ($decider eq "1") {goto KundenAnlegen;}
          if ($decider eq "2") {goto KundenSuchen;}
          if ($decider eq "3") {goto KurzgeschichteAnlegen;}
          if ($decider eq "4") {goto KurzgeschichteSuchen;}
          if ($decider eq "5") {goto BuchungsstatusAbfragen;}
          if ($decider eq "6") {goto StatistikAufrufen;}
          if ($decider eq "7") {goto ProgrammBeenden;}
          goto HauptMenu;
          
          ###################################################################
          KundenAnlegen:
          ###################################################################
          system("clear");
          print "+-----------------------------------------------------+ \n";
          print "| Einschlafzeit / Daten-Verwaltungs-Programm (EZ-DVP) | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print ">> Kunden anlegen << \n";
          print " \n";
          print "+-----------------------------------------------------+ \n";
          print "| [1] Daten eingeben...                               | \n";
          print "|                                                     | \n";
          print "| [2] Zurück...                                       | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print "Bitte Auftrag auswählen (1-2):";
          $decider = <STDIN>;
          chop($decider);
          if ($decider eq "1") {goto DatenEingeben;}
          if ($decider eq "2") {goto HauptMenu;}
          goto KundenAnlegen;
          exit;
          
          ###################################################################
          KundenSuchen:
          ###################################################################
          system("clear");
          print "+-----------------------------------------------------+ \n";
          print "| Einschlafzeit / Daten-Verwaltungs-Programm (EZ-DVP) | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print ">> Kunden suchen << \n";
          print " \n";
          print "+-----------------------------------------------------+ \n";
          print "| [1] Kunden suchen nach KD-Nummer...                 | \n";
          print "|                                                     | \n";
          print "| [2] Kunden suchen nach KD-Namen...                  | \n";
          print "|                                                     | \n";
          print "| [3] Zurück...                                       | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print "Bitte Auftrag auswählen (1-3):";
          $decider = <STDIN>;
          chop($decider);
          if ($decider eq "1") {goto SuchenKdNummer;}
          if ($decider eq "2") {goto SuchenKdNamen;}
          if ($decider eq "3") {goto HauptMenu;}
          goto KundenSuchen;
          exit;
          
          ###################################################################
          KurzgeschichteAnlegen:
          ###################################################################
          system("clear");
          print "+-----------------------------------------------------+ \n";
          print "| Einschlafzeit / Daten-Verwaltungs-Programm (EZ-DVP) | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print ">> Kurzgeschichte anlegen << \n";
          print " \n";
          print "+-----------------------------------------------------+ \n";
          print "| [1] Daten erfassen...                               | \n";
          print "|                                                     | \n";
          print "| [2] Zurück...                                       | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print "Bitte Auftrag auswählen (1-2):";
          $decider = <STDIN>;
          chop($decider);
          if ($decider eq "1") {goto DatenErfassen;}
          if ($decider eq "2") {goto HauptMenu;}
          goto KurzgeschichteAnlegen;
          exit;
          
          ###################################################################
          KurzgeschichteSuchen:
          ###################################################################
          system("clear");
          print "+-----------------------------------------------------+ \n";
          print "| Einschlafzeit / Daten-Verwaltungs-Programm (EZ-DVP) | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print ">> Kurzgeschichte suchen << \n";
          print " \n";
          print "+-----------------------------------------------------+ \n";
          print "| [1] Kurzgeschichte suchen nach KG-Nummer...         | \n";
          print "|                                                     | \n";
          print "| [2] Kurzgeschichte suchen nach KG-Titel...          | \n";
          print "|                                                     | \n";
          print "| [3] Zurück...                                       | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print "Bitte Auftrag auswählen (1-3):";
          $decider = <STDIN>;
          chop($decider);
          if ($decider eq "1") {goto SuchenKGNummer;}
          if ($decider eq "2") {goto SuchenKGTitel;}
          if ($decider eq "3") {goto HauptMenu;}
          goto KurzgeschichteSuchen;
          exit;
          
          ###################################################################
          BuchungsstatusAbfragen:
          ###################################################################
          system("clear");
          print "+-----------------------------------------------------+ \n";
          print "| Einschlafzeit / Daten-Verwaltungs-Programm (EZ-DVP) | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print ">> Buchungsstatus abfragen << \n";
          print " \n";
          print "+-----------------------------------------------------+ \n";
          print "| [1] Alle mit Status F (frei)...                     | \n";
          print "|                                                     | \n";
          print "| [2] Alle mit Status G (gebucht)...                  | \n";
          print "|                                                     | \n";
          print "| [3] Alle mit Status B (belegt)...                   | \n";
          print "|                                                     | \n";
          print "| [4] Zurück...                                       | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print "Bitte Auftrag auswählen (1-4):";
          $decider = <STDIN>;
          chop($decider);
          if ($decider eq "1") {goto StatusF;}
          if ($decider eq "2") {goto StatusG;}
          if ($decider eq "3") {goto StatusB;}
          if ($decider eq "4") {goto HauptMenu;}
          goto BuchungsstatusAbfragen;
          exit;
          
          ###################################################################
          StatistikAufrufen:
          ###################################################################
          system("clear");
          print "+-----------------------------------------------------+ \n";
          print "| Einschlafzeit / Daten-Verwaltungs-Programm (EZ-DVP) | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print ">> Statistik aufrufen << \n";
          print " \n";
          print "+-----------------------------------------------------+ \n";
          print "| [1] Werte anzeigen...                               | \n";
          print "|                                                     | \n";
          print "| [2] Zurück...                                       | \n";
          print "+-----------------------------------------------------+ \n";
          print " \n";
          print "Bitte Auftrag auswählen (1-2):";
          $decider = <STDIN>;
          chop($decider);
          if ($decider eq "1") {goto WerteAnzeigen;}
          if ($decider eq "2") {goto HauptMenu;}
          goto StatistikAufrufen;
          exit;
          
          ###################################################################
          ProgrammBeenden:
          ###################################################################
          system("clear");
          exit;