PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [PHP/MySQL] Teilstrings suchen



DHK
28.02.2007, 13:02
Hallo,
ich habe eine Frage bezüglich MySQL. Also ich habe in einem PHP-Skript folgende MySQL-Anweisung:


$sql = "SELECT Name FROM Audio WHERE Name='".$suchbegriff."';";

Das funktioniert auch sehr gut. Nun habe ich aber in meiner Datenbank eine Spalte "Stichwörter". Nun möchte ich diese Spalte nach Teilstrings durchsuchen, also in etwa so:


$sql = "SELECT Name FROM Audio WHERE Stichwörter='Teilstring';";

Allerdings weiß ich nicht, wie ich in MySQL einen Teilstring suchen kann. Schon mal vielen Dank für eure Hilfe.

Gruß

DHK

Wal
28.02.2007, 13:13
$sql = "SELECT Name FROM Audio WHERE Stichwörter LIKE '%Teilstring%';";


% ist dabei ein Platzhalter für beliebig viele Zeichen.

Sweil
28.02.2007, 13:24
Sehe ich das Richtig, dass deine Datenbank so aufgebaut ist:

Name | Stichwörter
x1 | Hallo, Ausprobieren, nix, noch weniger
x2 | muh, Kuh, Pflanze, BierWenn ja, dann muss ich dir erstmal sagen, dass das kein sauberer Datenbank aufbau ist. Du solltest lieber eine extra Tabelle mit Stichwörtern anlegen und die Stichwörter dann über eine id mit den restlichen Inhalten verbinden, also diese Tabellen:

Audio (ID, Name, etc...)
Stichwoerter (A.ID, Stichwort)

A.ID ist hier natürlich die Audio ID.

Dann kannst du die Stichwörter in der Stichwörter tabelle abfragen und mit der erhaltenen ID die restlichen Daten auslesen.

Außerdem solltest du umlaute lieber vermeiden. Normalerweise passiert da zwar nichts, aber es ist sozusagen kein guter "Umgangston"... ;)
_____________________________________________

Wenn du es aber nicht so machen möchtest, dann musst du die Feld mit dem like befehl abfragen, dabei wird nur nach einem Vorkommen des Teilstrings im Feld gesucht. DIe Verwendung wäre dann so:


$sql = "SELECT Name FROM Audio WHERE Stichwörter like '%Teilstring%';"; Die % sind Platzhalter für irgendwelche Zeichen.

DHK
28.02.2007, 13:28
Vielen Dank. Dann habe ich jetzt nur noch eine Frage zu CSS. Ausschnitt aus einer CSS-Datei:


div.suchergebnis:hover { background-color: #FFEEDD; }


Wie ihr seht, will ich, dass sich Bereich der Klasse "suchergebnis" beim Überfahren mit #FFEEDD; füllen. Beim Firefox klappt das auch wunderbar, nur dieser bescheurte IE 7 zeigts mal wieder richtig an. Muss ich das jetzt extra mit JavaScript (onMouseOver) lösen, oder gibt es andere Möglichkeiten, diesen sturen Microsoft-Browser zu überzeugen?

Gruß

DHK

edit: @Sweil: Soll ich dann in der Stichwörter-Tabelle die Stichwörter auch wieder mit LIKE abfragen? oder soll ich die Tabelle so aufbauen:


A.ID | Stichwort
--------------------
1 | Stichwort 1
1 | Stichwort 2
1 | Stichwort 3

Sweil
28.02.2007, 13:45
Das Problem ist eher, dass die Sachen wie hover, active, etc. sog. Pseudoklassen sind und mir bislang nur bekannt war, dass die mit dem a-tag (also bei links) funktionieren. Könnte daher sein, dass der FF das in der neusten Generation auch bei anderen elementen unterstützt. der IE tut das aber anscheinend nicht.

EDIT: Kommt es ganz drauf an was du erreichen willst. Wenn du das Stichwort "gut Mucke" auch bei der suche nach "gut" finden willst, dann nimmst du wieder like, wenn du es aber nur bei dem exakten begriff "gut Mucke" willst, dann mit dem =.

DHK
28.02.2007, 15:40
Ich habe mal noch eine Frage zu MySQL.
Angenommen, ich habe folgende Tabelle:


ID | Stichwort
-----------------------
2 | Glocke
4 | Glocke


Wie kann ich mir jetzt beide Einträge ausgeben lassen? Denn der findet immer nur den ersten mit der ID '2'.

Gruß

DHK

Sweil
28.02.2007, 15:58
Du musst dir die Ergebnisse mit einer while-Schleife holen:


$index = mysql_query($sql, $db);
while ($daten= mysql_fetch_assoc($index))
{
//Verarbeitung der Daten
}
$index enthält einfach den mysql_query wie du ihn sonst auch hast, alternativ kannst du du mysql_query natürlich auch in die klammer hinter assoc schreiben.

alle daten hast du dann in dem array $daten die array keys sind dabei die namen der tabellen spalten.

Außer natürlich du hast LIMIT 1 hinten dran gehängt, dann liegt es daran. :p

DHK
28.02.2007, 16:16
Hmm...das funzt irgendwie nicht:


<?php
include "config.php";
mysql_verbindung_aufbauen();

# Variablen definieren
$suchbegriff = $_POST['begriff'];
$suchbereich = $_POST['bereich'];
$html_head = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>Scrutator-Audio</title><link rel="stylesheet" href="design.css"></head><body>';
$html_ende = '</body></html>';

# Zugriff auf MySQL
$sql = "SELECT ID FROM Audio_Stichwoerter WHERE Stichwort LIKE '%".$suchbegriff."%';";
$result = mysql_query($sql) OR die(mysql_error());
while ($ergebnis2= mysql_fetch_assoc($result)) {
//print_r($ergebnis2);
$sql = "SELECT Name, Beschreibung, Dateityp, Groesse, URL, Qualitaet FROM Audio WHERE ID='".$ergebnis2['ID']."';";
}
$result = mysql_query($sql) OR die(mysql_error());
while ($ergebnis= mysql_fetch_assoc($result))
{
//print_r($ergebnis);
if($ergebnis['Name'] != "") {
echo $html_head;
include "suchvorlage.html";
echo '<div id="suchformular" class="suchergebnis">';
for($i=0;$i<$ergebnis['Qualitaet'];$i++) {
echo '<img src="Stern.png" width="16" height="16" />';
}
echo '&nbsp;&nbsp;<a href="'.$ergebnis['URL'].'">'.$ergebnis['Name'].'</a><br>';
echo '<span>'.$ergebnis['Beschreibung'].'</span><br>';
echo '<span class="grau">'.$ergebnis['Groesse'].'&nbsp;&nbsp;&bull;&nbsp;&nbsp;Dateityp: '.$ergebnis['Dateityp'].'</span>';
echo '</div>';
echo $ergebnis[6];
echo $html_ende;
}
}
?>


Das ist z. Z. mein Skript. Leider wird nach wie vor nur ein Ergebnis ausgegeben. Hab mir die Arrays $ergebnis2 und $ergebnis mal mit print_r() ausgeben lassen -> $ergebnis2 hat sowohl die IDs 2 als auch 4 als Werte, ausgegeben wird durch $ergebnis schlussendlich aber nur ID 4.

Gruß

DHK

Sweil
28.02.2007, 21:56
naja so kann das auch nicht funktionieren. in jedem while-schleifen durchlauf beschreibst du ja $sql neu und im letzten durchgang hat die ID eben den Wert 4.

Um da raus zu kommen müsste ich aber genauer wissen, was du machen möchtest. Wenn ich es richtig verstanden habe, dann willst du für jeden eintrag der zu dem suchbegriff gefunden wird einen bestimmten datensatz ausgeben?

dann ist deine zweite while schleife überflüssig. dafür musst den inhalt der zweiten in die erste mit reinkopieren. den du willst ja für jeden gefundenen suchbegriff die passenden daten ausgeben. da die schleife für jedes mal finden einmal durchlauft musst du die ausgabe auch in diesen durchlauf mit reinpacken. den die der CD (oder was auch immer du da suchst) ist ja immer eindeutig (sollte sie zumindest).

was aber auch problematisch ist, ist dass du den html anfang, das ende und das suchformular in einer schelife ausgibst. bei deinem code wird das alles zwar nur einmal ausgegeben (wegen der einmaligen ID) aber theoretisch könnte es dann mehrmals ausgegeben werden. als den html anfang und das suchformular vor der schleife ausgeben, dann den inhalt ausgeben und dannach das ende ausgeben.

DHK
01.03.2007, 13:16
Also, ich erkläre nochmal, was ich machen möchte und wie ich es machen möchte (sofern das möglich ist):
Ich habe ein Tabelle in einer MySQL-Datenbank:


ID | Stichwort
-----------------------
2 | Glocke
4 | Glocke


Dazu habe ich ein Eingabefeld in einem Suchformular. Wenn der Benutzer jetzt 'Glocke' eingibt, soll nicht nur das Ergebnis mit der ID '4' ausgegeben werden, sondern auch das mit der ID '2'.
So. Der Benutzer hat jetzt 'Glocke' eingegeben und auf den Suchen-Button gedrückt. Das PHP-Skript soll jetzt in oben genannter Tabelle nach dem Teilstring 'Glocke' suchen. Dabei soll es zwei IDs finden (was es auch tut): '2' und '4'. Diese gefundenen IDs soll es jetzt in einer anderen Tabelle finden, die ungefähr so aufgebaut ist:


Name | Beschreibung | Qualitaet | Groesse | URL | ID
-------------------------------------------------------------------------------
bla | blabliblu | 5 | 142 KB | http://www.blabliblu.bla | 2
blu | blubliblo | 5 | 241 KB | http://www.blubliblo.blu | 4


Und diese beiden Ergebnisse soll er ausgeben. Das bisherige Problem ist, dass er nur das Ergebnis mit der ID 4 (also 'blu' ausgibt).
Das bisherige Skript findet ihr in meinem oberen Beitrag.

Gruß

DHK

Niwa Daisuke
01.03.2007, 13:25
Heißt im Klartext, dass du alle Posts ignorierst, die keinen Code beinhalten, auch, wenn die Lösung (zumindest zu einem Teil) deines Problems beschrieben wurde?

DHK
01.03.2007, 13:34
Ich bin kein Ignorant. Nur muss ich halt Sweils Vorschläge auch umsetzen, auf den Server hochladen, etc. Und da ihm anscheinend nicht ganz klar war, was ich machen will, habe ich es nochmal erklärt. Ich kann dir nicht zustimmen, dass ich alle Beiträge ohne Code ignoriere und deine Feststellung ist mit Sicherheit falsch.

Gruß

DHK

edit: @Sweil: Habe die von dir angestrebten Änderungen (hoffentlich richtig) durchgeführt. Es wird aber nach wie vor nur ein Ergebnis ausgegeben:


# ....
# Zugriff auf MySQL
$sql = "SELECT ID FROM Audio_Stichwoerter WHERE Stichwort LIKE '%".$suchbegriff."%';";
$result = mysql_query($sql) OR die(mysql_error());
while ($ergebnis2= mysql_fetch_assoc($result)) {
//print_r($ergebnis2);
$sql = "SELECT Name, Beschreibung, Dateityp, Groesse, URL, Qualitaet FROM Audio WHERE ID='".$ergebnis2['ID']."';";
$result = mysql_query($sql) OR die(mysql_error());
$ergebnis = mysql_fetch_row($result);
if($ergebnis[0] != "") {
echo '<div id="suchformular" class="suchergebnis">';
for($i=0;$i<$ergebnis[5];$i++) {
echo '<img src="Stern.png" width="16" height="16" />';
}
echo '&nbsp;&nbsp;<a href="'.$ergebnis[4].'">'.$ergebnis[0].'</a><br>';
echo '<span>'.$ergebnis[1].'</span><br>';
echo '<span class="grau">'.$ergebnis[3].'&nbsp;&nbsp;&bull;&nbsp;&nbsp;Dateityp: '.$ergebnis[2].'</span>';
echo '</div>';
}
}
# ....

Wal
01.03.2007, 15:52
Hm... du nennst die Variable mit dem SQL-Ergebnis $result, diese wird jedoch innerhalb der While-Schleife überschrieben. Und da die innerhalb der While-Schleife ausgeführte SQL-Abfrage natürlich nur ein Ergebnis zurückliefert, läuft diese auch nur einmal durch. Meiner Meinung nach liegt es also daran, dass du beide SQL-Results $result genannt hast. Ich hätte da aber auch noch eine Lösung mit nur einem SQL-Befehl (was performanter sein sollte):


$sql = "SELECT Name, Beschreibung, Dateityp, Groesse, URL, Qualitaet FROM Audio_Stichwoerter a INNER JOIN Audio b ON (a.ID = b.ID) AND a.Stichwort LIKE '%".$suchbegriff."%' ";
$result = mysql_query($sql) OR die(mysql_error());
while ($ergebnis = mysql_fetch_row($result)) {
if($ergebnis[0] != "") {
echo '<div id="suchformular" class="suchergebnis">';
for($i=0;$i<$ergebnis[5];$i++) {
echo '<img src="Stern.png" width="16" height="16" />';
}
echo '&nbsp;&nbsp;<a href="'.$ergebnis[4].'">'.$ergebnis[0].'</a><br>';
echo '<span>'.$ergebnis[1].'</span><br>';
echo '<span class="grau">'.$ergebnis[3].'&nbsp;&nbsp;&bull;&nbsp;&nbsp;Dateityp: '.$ergebnis[2].'</span>';
echo '</div>';
}
}
Habs nicht getestet, sollte aber so funktionieren.

Sweil
01.03.2007, 20:24
Mit nem INNER JOIN geht das natürlich auch, die Frage ist nur, ob man das einem (offensichtlichen) MySQL Neuling gleich mit auf den Weg geben sollte. Ich meine er sollte doch besser verstehen, was er da tut. ;)

Und dass dein Script oben nicht funktioniert liegt, wie Wal schon gesagt hat an der falschen (bzw. doppelten) Benennung.

DHK
02.03.2007, 13:17
Vielen Dank @Wal und @Sweil.
Es gibt jetzt nur noch ein einziges Problem. Also ich habe folgende Einträge in meiner Tabelle:


ID | Stichwort
-----------------
2 | Glocke
2 | Kirchturmglocke
2 | Kirchturm-Glocke

Gebe ich nun ins Suchfeld "Glocke" ein, wird dreimal das gleiche Ergebnis ausgegeben. Wer's probieren möchte, kann es hier (http://www.werbung-fuer-sie.de/test/only_audio.html) tun.
Hat jemand eine Idee, wie man die Ausgabe von mehreren identischen Ergebnissen vermeiden kann?

Gruß

DHK

Kermit
02.03.2007, 13:44
Wenn ich kurz was anderes zwischen schieben darf. Ich weiß nicht wofür das Script gedacht ist, aber sollte es Teil einer öffentlichen Seite sein, würde ich mich mal ein wenig mit Scriptsicherheit auseinander setzen.



$suchbegriff = $_POST['begriff'];
[...]
$sql = "SELECT ID FROM Audio_Stichwoerter WHERE Stichwort LIKE '%".$suchbegriff."%';";
$result = mysql_query($sql) OR die(mysql_error());


Du schickst hier eine ungefiltere Formulareingabe schnurstacks zu deiner Datenbank weiter. Üebrleg zB mal wozu dieser Suchbegriff hier führen könnte:


blablub'; DROP TABLE Audio_Stichwoerter;

DHK
02.03.2007, 15:09
Hallo Kermit (hast du früher nicht mal Kermit.d geheißen? :confused:).
Danke für deinen Hinweis. Ich wollte aber erst sichergehen, dass die Suchanfrage überhaupt funktioniert, bevor ich mich mit der Sicherheit des Skriptes auseinandersetzte. Trotzdem §danke

Gruß

DHK