wirreparieren: Formulardaten in MYSQL DB erfassen und verteilen

Hallo WISSENDE, ich verzweifle, weil überhaupt keine Idee wie ich einer Lösung näher kommen kann.

Tabelle t_anfrage_web

 (
  `IdSession` varchar(30) NOT NULL DEFAULT '',
  `subip` varchar(20) DEFAULT NULL COMMENT 'user IP',
  `username` varchar(50) DEFAULT NULL,
  `userEmail` varchar(150) DEFAULT NULL,
  `dienstleistungen` varchar(255) DEFAULT NULL,
  `d_erfass` date DEFAULT NULL,
  `del` binary(1) DEFAULT '0' COMMENT 'delete',
  `d_aktuell` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`IdSession`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Online Anfrage XYZ auch ohne login';

ist mit folgenden Daten gefüllt

IdSession '101'
subip '192.168.0.100'
username 'ich'
userEmail 'auchich@ich.de'
dienstleistungen 'Mobil1 ***br****Mobil2***br***Mobil3***br****Mobil4'
d_erfass '2019-01-17 10:02:03'
del '0'
d_aktuell '2019-01-17 10:02:03'

Ich habe keinen Einfluss auf die Datenstruktur, da sie über Formular(Formmaker) in der Datenbank abgelegt wird.

Ich kann die dienstleistungen aber so nicht gebrauchen, sondern will die Details in Neuer Tabelle haben:

Tabelle neu
ID, IdSession, Dienstleistung
1, 101, Mobil1
2, 101, Mobil2
3, 101, Mobil3
4, 101, Mobil4

Nun die Frage, wie kann ich das Problem lösen, hat jemand eine Idee??

Trigger after submit? aber wie bekomme ich die Werte aufgeteilt? keine Ahnung

akzeptierte Antworten

  1. Hallo WISSENDE, ich verzweifle, weil überhaupt keine Idee wie ich einer Lösung näher kommen kann.

    Code:

    Bitte markiere Deinen Quelltext als Code. Dafür gibt es die Taste </>. Wenn Du auf Antworten klickst siehst Du auch, wie Du das "von Hand" machen kannst.

    Tabelle `t_anfrage_web`
     (
      `IdSession` varchar(30) NOT NULL DEFAULT '',
      `subip` varchar(20) DEFAULT NULL COMMENT 'user IP',
      `username` varchar(50) DEFAULT NULL,
      `userEmail` varchar(150) DEFAULT NULL,
      `dienstleistungen` varchar(255) DEFAULT NULL,
      `d_erfass` date DEFAULT NULL,
      `del` binary(1) DEFAULT '0' COMMENT 'delete',
      `d_aktuell` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`IdSession`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Online Anfrage XYZ auch ohne login';
    

    ist mit folgenden Daten gefüllt

    Code:

    IdSession '101'
    subip '192.168.0.100'
    username 'ich'
    userEmail 'auchich@ich.de'
    dienstleistungen 'Mobil1 ***br****Mobil2***br***Mobil3***br****Mobil4'
    d_erfass '2019-01-17 10:02:03'
    del '0'
    d_aktuell '2019-01-17 10:02:03'
    

    Ich habe keinen Einfluss auf die Datenstruktur, da sie über Formular(Formmaker) in der Datenbank abgelegt wird.

    Ich kann die dienstleistungen aber so nicht gebrauchen, sondern will die Details in Neuer Tabelle haben: Code:

    Tabelle neu
    ID, IdSession, Dienstleistung
    1, 101, Mobil1
    2, 101, Mobil2
    3, 101, Mobil3
    4, 101, Mobil4
    

    Nun die Frage, wie kann ich das Problem lösen, hat jemand eine Idee??

    Trigger after submit? aber wie bekomme ich die Werte aufgeteilt? keine Ahnung

    Hier ist der Knackpunkt:

    Ich habe keinen Einfluss auf die Datenstruktur, da sie über Formular(Formmaker) in der Datenbank abgelegt wird.

    Es gibt laut Suchmaschine meines unerhörten Misstrauens mindestens 300 "Formmaker". Für jeden einzelnen davon gilt:

    1. Man kann sie nur verwenden, wenn man sie zu verwenden weiß.
    2. Kann der verwendete "Formmaker" die Daten nicht in der gewünschten Struktur liefern hat man vier Möglichkeiten:
    • keinen der "Formmaker" verwenden,
    • einen anderen "Formmaker" verwenden,
    • die erzeugten Formulare nur als Vorschläge ansehen und nachbearbeiten und/oder
    • die mit den erzeugten Formularen gesendeten Daten vor dem Eintrag in die Datenbank mittels Software auswerten und entsprechend "umformulieren". Das ist ja (abgesehen von Fileuploads natürlich) alles nur Text.

    Die Möglichkeiten dazu sind unendlich, also nicht darstellbar.

    Übrigens ist die Datenstruktur einer der Kernpunkte der Programmplanung und wird sehr früh gemacht. Gibt es einen Plan für das Programm oder wird da rumgeschustert?

    1. Erst mal danke für den Hinweis mit der Formatierung.

      Jetzt zu deinen Fragen,

      1. Formmaker ist gesetzt, habe keinen Einfluß darauf 😟
      2. ... werde ich mir anschauen, wobei kein Formmaker momentan nicht so einfach ist ... Bearbeiten des String 'dienstleistungen' wäre ein Möglichkeit, da muss ich awk auspacken. Mein Gott ist das Lange her.

      Die Datenstruktur steht, war neben einer globalen Zielstellung die erste Arbeit. Auch die erforderlichen Ansichten sind soweit fertig und funtionieren mit Testdaten, nur der String lässt uns verzweifeln. Trotzdem Danke für die Bemühungen, hat mich sehr gefreut.

    2. Lösung gefunden, wenn auch nicht schön aber effektiv, Falls jemand da etwas braucht

      drop table if exists v_tmp;
      create Table v_tmp as (
      select * from(
      select 1 AS idtmp, max(Idsession) as IdSession, replace(replace(substring_index(dienstleistungen, ';', 1),substring_index(dienstleistungen, ';', 1 - 1),''),';','') as dienstleistung
      from t_anfrage_web
      where IdSession = (select max(IdSession) from t_anfrage_web)
      union all
      select 2 AS idtmp, max(Idsession) as IdSession, replace(replace(substring_index(dienstleistungen, ';',2),substring_index(dienstleistungen, ';', 2 - 1),''),';','') as dienstleistung
      from t_anfrage_web
      where IdSession = (select max(IdSession) from t_anfrage_web)
      union all
      select 3 AS idtmp, max(Idsession) as IdSession, replace(replace(substring_index(dienstleistungen, ';',3),substring_index(dienstleistungen, ';', 3 - 1),''),';','') as dienstleistung
      from t_anfrage_web
      where IdSession = (select max(IdSession) from t_anfrage_web)
      union all
      select 4 AS idtmp, max(Idsession) as IdSession, replace(replace(substring_index(dienstleistungen, ';',4),substring_index(dienstleistungen, ';', 4 - 1),''),';','') as dienstleistung
      from t_anfrage_web
      where IdSession = (select max(IdSession) from t_anfrage_web)
      union all
      select 5 AS idtmp, max(Idsession) as IdSession, replace(replace(substring_index(dienstleistungen, ';',5),substring_index(dienstleistungen, ';', 5 - 1),''),';','') as dienstleistung
      from t_anfrage_web
      where IdSession = (select max(IdSession) from t_anfrage_web)
      ) tmp where Dienstleistung != '');
      
      insert into Tabelle_neu(idtmp, IdSession, dienstleistung) SELECT * from v_tmp  
      

      Geht sicher zu optimieren,

      Bis bald.

      1. Geht sicher zu optimieren,

        Klar. Was ich sehe ist wie in folgendem Dialog:

        Hier ist eine gewaltige Maschine. Presst damit linke und rechte Kotflügel. Chef! Problem: Die Maschine kann nur linke Kotflügel! Dann presst eben erst mal linke Kotflügel, deklariert die als Schrott und nehmt eine weitere, noch gewaltigere und mächtig gewaltig teure Maschine um aus dem Schrott rechte Kotflügel zu pressen.

        1. Guten Morgen, was soll ich machen, wenn nur eine Maschine (Formmaker) da ist. Auf alle Fälle bekomme ich ich einzeln ausgewählten ordentlich in eine Tabelle geschrieben. Chef will halt keine Maschine f2 Kotflügel kaufen......!

          Wenn dir zu Optimierung etwas einfällt, nehme ich Hinweise gern an.

          1. Normalerweise baut man eine Datenstruktur da um wo sie ankommt: In der serverseitigen Anwendung hinter dem Formular. Also da wo man sie im wahlfreien Zugriff hat.

            MfG

  2. Hallo wirreparieren,

    das Datenmodell ist nicht normalisiert und das ist dann die Konsequenz. Die Dienstleistungen gehören nicht in eine einzige Spalte, auch nicht in eine Zeile.

    Die Operation, um die von dir gewünschte Transformation auszuführen, heißt UNPIVOT (als Gegenteil von PIVOT) und ist auch in MySQL 8 noch nicht vorhanden. D.h. der UNION ALL Workaround ist richtig.

    Besser wäre natürlich eine von Anfang an richtige Datenstruktur...

    Rolf

    --
    sumpsi - posui - clusi
    1. Danke Rolf, ich kann mich nur wiederholen, die Datenbank ist sauber strukturiert nur die Übergabe der Daten aus Formmaker ist mein Problem, kann ich nicht ändern. Da immer nur max. 5 "Datensätze" im String sind, geht die Aufteilung auch relativ schnell von statten. Ist zwar nicht schön aber funktioniert.

      1. Hallo wirreparieren,

        Da immer nur max. 5 "Datensätze" im String sind,

        vs

        ich kann mich nur wiederholen, die Datenbank ist sauber strukturiert

        Solange die DB - mit deiner eigenen Aussage bestätigt - nicht mal in 1. Normalform ist (keine strukturierten Attribute), kann ich auch nur wiederholen: Nein, ist sie nicht.

        Möglicherweise lässt Dir der Formmaker keine andere Wahl. Das macht es aber nicht sauber. Und die Konsequenzen bekommst Du zu spüren. Ein UNPIVOT sollte bei einem guten DB Design nicht erforderlich sein, höchstens mal ein PIVOT.

        Rolf

        --
        sumpsi - posui - clusi