Carlo: [MySQL] Strukturierte Ausgabe?

Hallo!

Ich habe mich als DB-Anfänger bislang zwar durch vieles gekämpft, hierauf fand ich aber keine zufriedenstellende Antwort:

Es handelt sich um eine kleine Adresssammlung. Über ein HTML-Formular kann der Seitenbesucher per Checkbox wählen, wo der ebenfalls dort einzugebende Suchbegriff gesucht werden soll (Spalten mit Name, Ort, Postleitzahl etc.) und wählte zuvor per Radiobutton aus, in welchem Gebiet er das Stichwort suchen möchte ($_POST[thema]).

Nach diversen Kontrollen (Mindesteingrenzungen, real_escape_string usw.) habe ich nun ...

if($_POST[adrart]=="ja"){$abfrage1=mysql_query("SELECT*FROM adr WHERE top='$_POST[thema]' AND art LIKE '$suche'");while($ausgabe=mysql_fetch_array($abfrage1)){echo "$ausgabe[name]<br />";}}
if($_POST[adrort]=="ja"){$abfrage2=mysql_query("SELECT*FROM adr WHERE top='$_POST[thema]' AND ort LIKE '$suche'");while($ausgabe=mysql_fetch_array($abfrage2)){echo "$ausgabe[name]<br />";}}
if($_POST[adrvname]=="ja"){$abfrage3=mysql_query("SELECT*FROM adr WHERE top='$_POST[thema]' AND vname LIKE '$suche'");while($ausgabe=mysql_fetch_array($abfrage3)){echo "$ausgabe[name]<br />";}}

... (usw.) eingebaut. Damit ergeben sich bei einer Vielfachauswahl wegen der ggf. in mehreren Zellen einer Zeile auftretenden Inhaltsbestandteile zig doppelt angezeigte Zeilen (Ortsangaben in dem Ort, dem Firmennamen, der URL etc.). Das provisorische "$ausgabe[name]" ersetze ich dann durch einen Link zur vom Besucher auszuwählenden einzelnen "Datenzeile".

Weil ich ungern mit langen "if"-Schachtelungen oder var-Kombinationswerten (für alle mögliche Auswahlkombinationen) arbeiten möchte, würde ich mich über einen übersichtlicheren Vorschlag (oder einen, wie ich die Dopplungen im Anschluss nicht doppelt anzeigen lassen muss) freuen.

Ansonsten habe ich noch nicht herausbekommen, wie ich vom Besucher eventuell eingegebene _ und % (Platzhalter) herausfiltern kann. Bei allen meiner Ersetzungs-/Maskierungsversuche kam nur ein entstelltes Datenergebnis heraus :-(

Danke und Gruß :-)

  1. Tach!

    Es handelt sich um eine kleine Adresssammlung. Über ein HTML-Formular kann der Seitenbesucher per Checkbox wählen, wo der ebenfalls dort einzugebende Suchbegriff gesucht werden soll (Spalten mit Name, Ort, Postleitzahl etc.) und wählte zuvor per Radiobutton aus, in welchem Gebiet er das Stichwort suchen möchte ($_POST[thema]).

    Mach doch eine Abfrage und stelle für diese die Bedingungen zusammen anstatt für jede Bedingung eine eigene Abfrage zu erstellen.

    Nach diversen Kontrollen (Mindesteingrenzungen, real_escape_string usw.) habe ich nun ...

    Von mysql_real_escape_string() ist aber im gezeigten Code nichts zu sehen. Es ist nicht günstig, das an anderer Stelle als beim Statement-Zusammenbau zu machen. Wenn du dir wegen der einzubauenden Funktionsaufrufe Sorgen um die Lesbarkeit des Statements machst, dann nimm sprintf().

    Ansonsten habe ich noch nicht herausbekommen, wie ich vom Besucher eventuell eingegebene _ und % (Platzhalter) herausfiltern kann. Bei allen meiner Ersetzungs-/Maskierungsversuche kam nur ein entstelltes Datenergebnis heraus :-(

    Wie man diese Zeichen maskiert, steht im MySQL-Handbuch auf der Seite, die LIKE beschreibt. PHP bietet dafür keine eigene Funktion, du kannst das mit einfachem String-Ersetzung hinbekommen (beispielsweise strtr(), zweite Variante).

    dedlfix.

    1. Mach doch eine Abfrage und stelle für diese die Bedingungen zusammen anstatt für jede Bedingung eine eigene Abfrage zu erstellen.

      Das wollte ich anfangs auch tun, doch war der Zusammenbau des SELECT-Teils mein gedankliches Problem. Wie ist es hier möglich, die vorkommenden Auswahlkombinationen (einzelne Spalten (nicht) durchsuchen) _ohne_ alle einzelnen Möglichkeiten (wie per vorgelagerter Abfrage usw.) explizit beschrieben zu bedienen, zumal ja auch das Auftauchen des jeweils ersten OR "geplant" werden muss. An anderen Stellen habe ich ebendies genutzt, doch dürfte der Aufwand zukünftig hinzukommender Spalten und deren Abfragemöglichkeit entsprechend viele neue Kombinationsdefinitionen nach sich ziehen ...

      Von mysql_real_escape_string() ist aber im gezeigten Code nichts zu sehen. Es ist nicht günstig, das an anderer Stelle als beim Statement-Zusammenbau zu machen. Wenn du dir wegen der einzubauenden Funktionsaufrufe Sorgen um die Lesbarkeit des Statements machst, dann nimm sprintf().

      Konkret ist es so: Gleich nach dem Formularcode baue ich die Verbindung zur DB auf und wende mysql_real_escape_string noch vor den anderen Abfragen (Mindestspaltenwahl u.ä.) an; nach diesem Kontrollblock folgen dann die angeführten if-Abfragen. Lässt sich dies tatsächlich durch eine mql_real_escape_string-Verlegung optimieren?

      Wie man diese Zeichen maskiert, steht im MySQL-Handbuch auf der Seite, die LIKE beschreibt. PHP bietet dafür keine eigene Funktion, du kannst das mit einfachem String-Ersetzung hinbekommen (beispielsweise strtr(), zweite Variante).

      Ja, danke.

      1. Mach doch eine Abfrage und stelle für diese die Bedingungen zusammen anstatt für jede Bedingung eine eigene Abfrage zu erstellen.

        Das wollte ich anfangs auch tun, doch war der Zusammenbau des SELECT-Teils mein gedankliches Problem. Wie ist es hier möglich, die vorkommenden Auswahlkombinationen (einzelne Spalten (nicht) durchsuchen) _ohne_ alle einzelnen Möglichkeiten (wie per vorgelagerter Abfrage usw.) explizit beschrieben zu bedienen, zumal ja auch das Auftauchen des jeweils ersten OR "geplant" werden muss. An anderen Stellen habe ich ebendies genutzt, doch dürfte der Aufwand zukünftig hinzukommender Spalten und deren Abfragemöglichkeit entsprechend viele neue Kombinationsdefinitionen nach sich ziehen ...

        Aktualisierung: Hat doch noch geklappt. Ich habe aus den $_POST-Auswahlmöglichkeiten neue Variablen erzeugen lassen (damit die Originalauswahl erhalten bleibt), aus den OR-Abfrageergänzungen entsprechende Variablen für jede Spalte gemacht, die SELECT-Zeile um diese ergänzt und die ausgelagerte Auswahlvariable bei dann schon getätigter Anzeige als nicht gewählt geleert (die Originalauswahl bleibt ja in der $_POST[]-var erhalten, falls sie später nochmals benötigt wird). Somit wird nur noch eines der mysql_query-Konstrukte ausgeführt.

        Kann man das als sinnvoll gelöst betrachten oder würde etwas anderes mit geringerem Zeichenaufwand (alles in einer mysql_query?) zum Ziel führen?

      2. Tach!

        Mach doch eine Abfrage und stelle für diese die Bedingungen zusammen anstatt für jede Bedingung eine eigene Abfrage zu erstellen.
        Das wollte ich anfangs auch tun, doch war der Zusammenbau des SELECT-Teils mein gedankliches Problem. Wie ist es hier möglich, die vorkommenden Auswahlkombinationen (einzelne Spalten (nicht) durchsuchen) _ohne_ alle einzelnen Möglichkeiten (wie per vorgelagerter Abfrage usw.) explizit beschrieben zu bedienen, zumal ja auch das Auftauchen des jeweils ersten OR "geplant" werden muss. An anderen Stellen habe ich ebendies genutzt, doch dürfte der Aufwand zukünftig hinzukommender Spalten und deren Abfragemöglichkeit entsprechend viele neue Kombinationsdefinitionen nach sich ziehen ...

        So wie ich das verstehe, hast du eine Reihe Bedingungen und der Anwender sagt, welche davon genommen werden sollen. Letztlich weißt du nicht, wieviele das werden, musst aber flexibel die WHERE-Teile erstellen. Geh doch so vor: Erstelle zunächst ein leeres Array. Dann geh durch alle Eingaben durch und füge dem Array die gewählten Teilbedingungen zu und zwar ohne Verknüpfungen zwischen ihnen. Am Ende hat das Array beliebig viele Einträge, welche du mit implode() und einem " OR " als Leim zu einer Gesamtbedingung zusammenfügen kannst.

        Konkret ist es so: Gleich nach dem Formularcode baue ich die Verbindung zur DB auf und wende mysql_real_escape_string noch vor den anderen Abfragen (Mindestspaltenwahl u.ä.) an; nach diesem Kontrollblock folgen dann die angeführten if-Abfragen. Lässt sich dies tatsächlich durch eine mql_real_escape_string-Verlegung optimieren?

        Es ist ungünstig, wenn du die Maskierung zu den Originaldaten hinzufügst. Diese sind dann für weitere Verwendungen außer dem SQL-Statement gestorben, ohne dass du die Maskierung wieder rückgängig machst. Es ist besser, die Werte in ihrer Rohform zu lassen und nur bei Bedarf die Maskierung direkt beim Einfügen in den jeweiligen Kontext vorzunehmen.

        dedlfix.