Kriterien für Select durch Textfelder generieren lassen?

Kriterien für Select durch Textfelder generieren lassen?

am 29.03.2007 15:50:25 von g.thaler

Ich versuche mich seitkurzer Zeit in PHP+MySQL und habe eine Tabelle
filme mit folgenden Feldern:

fid (Film-ID, Primary Key)
---
namedt (Deutscher Filmtitel)
nameor (Titel in der Originalsprache)
regie
jahr
imdb (Link zur Seite von imdb.de)
note
anmerkung


Des Weiteren habe ich ein Formular mit vier Textfeldern. Der Anwender
soll wahlweise ein Textfeld, zwei, drei oder alle vier Felder befüllen.
Damit hat er die Suchkriterien festgelegt.

Nach Absenden des Formulars soll eine Abfrage mit den soeben erzeugten
Auswahlkriterien abgeschickt werden.

Hier das Skript (da ich blutiger Anfänger bin, habe ich umständliche
Kommentare für mich eingefügt)

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXX





// 1. PHP-Block
#--------------

// Überprüfung, ob das Formular schon einmal abgeschickt worden ist

if (isset($_POST["sent"]))
{

// Angabe der Datenbank-Zugangsdaten

$host = "localhost";
$user = "my_username";
$password = "my_password";
$dbname = "my_database";
$verbid = mysql_connect($host, $user, $password);


// Auswahl und Aktivierung der Datenbank

mysql_select_db($dbname);


// Bau der SQL-Anweisung:

$sql = "SELECT fid, namedt, nameor, regie, jahr, imdb, note,
anmerkung ";
$sql .= "FROM filme ";
$sql .= "WHERE namedt = " . $_POST['titel_dt'] . " AND nameor = " .
$_POST['titel_or'] . " AND regie = " . $_POST['director'] . " AND jahr
= " . $_POST['year'] . " ";
$sql .= "ORDER BY namedt";

echo $sql;


// Jetzt wird ein SELECT abgesetzt und die Ergebnis-ID in $ergid
geschrieben.

$ergid = mysql_query($sql, $verbid);

echo $ergid;





// Anzahl der Datensätze bestimmen:

$num = mysql_num_rows($ergid);





// Schleife: Ausgabe der Datensätze:
#-----------------------------------

# Nun wird eine For-Schleife programmiert mit der Anfangsbedingung i =
0 und der Abbruchbedingung i < der Wert von $num.
# Zuerst zur Funktion

# Zuerst zur Funktion mysql_result():
# mixed mysql_result ( resource Ergebnis-Kennung, int Datensatz [, mixed
feld] ) liefert den Inhalt eines Felds aus einem Anfrageergebnis.
# Das Argument feld kann der Feldname, der Feldoffset ein Bezeichner in
der Form 'Tabellenname.Feldname.' sein.
# Wenn das Feld einen Alias besitzt ('select foo as bar from...') muss
der Alias anstatt des Feldnamens verwendet werden.

# Wenn auf Anfrageergebnisse mit vielen Datensätzen zugegriffen werden
soll, sollten Sie Funktionen, die auf ganze Datensätze zugreifen,
# in Betracht ziehen (vgl. unten). Diese Funktionen liefern bei einem
einzigen Aufruf den Inhalt mehrerer Felder und sind aus diesem
# Grund SEHR viel schneller als mysql_result(). Beachten Sie auch, dass
die Angabe eines numerischen Offsets für ein Feld sehr viel
# schneller ist als die Angabe eines Feldnamens oder tabellenname.feldname.

# Alternativen: mysql_fetch_row(), mysql_fetch_array(),
mysql_fetch_assoc() und mysql_fetch_object().

# Aufrufe von mysql_result() sollten nicht mit Aufrufen anderer
Funktionen verschachtelt werden, die auch auf das Ergebnis zugreifen.

# Also ergeht rein in die Schleife und weist der Variablen $$nn jenen
Wetrt zu, den wie Funktion mysql_result() hat, wenn sie aufgerufen
# worden ist. Dann weist er der Variablen $vn den Wert des Feldes
#

for ($i=0; $i<$num; $i++)
{
$filmid = mysql_result($ergid, $i, "fid");
$ndt = mysql_result($ergid, $i, "namedt");
$nor = mysql_result($ergid, $i, "nameor");
$director = mysql_result($ergid, $i, "regie");
$year = mysql_result($ergid, $i, "jahr");
$url = mysql_result($ergid, $i, "imdb");
$bew = mysql_result($ergid, $i, "note");
$anm = mysql_result($ergid, $i, "anmerkung");

// Die eigentliche Listenausgabe:
#-----------------------------------
# Hier sollte natürlich layouttechnisch formatiert werden.

echo " DVD-Nummer: $fid Deutscher Titel: target=\"blank\">$ndt
Originaltitel: $nor
Regie:
$director
Jahr: $year


";
}

// Datenbank-Verbindung beenden (wichtig):
#----------------------------------------
# Nun muss die DB-Verbindung wieder beendet wedren, um die Datenbank zu
entlasten.

mysql_close($verbid);

}
?>





Willkommen bei der Film-Datenbank


Geben Sie Ihre Suchkriterien ein und klicken Sie auf "Absenden".








Titel (deutsch.):


Titel (Originalsprache): maxlength="50">


Regie:


Jahr:














============================================================ ==========

Nur: wie soll ich die Abfrage bauen? Ich erhalte:

"Warning: mysql_num_rows(): supplied argument is not a valid MySQL
result resource in /home/thaler/public_html/film/standard.php on line 48"

Wenn der Anwender nur ein Textfeld beschreibt, müsste die Abfrage lauten:

$sql = "SELECT fid, namedt, nameor, regie, jahr, imdb, note,
anmerkung ";
$sql .= "FROM filme ";
$sql .= "WHERE namedt = " . $_POST['titel_dt'] . " ";
$sql .= "ORDER BY namedt";


Wenn der Anwender die ersten beiden Textfelder als Kriterien benutzt,
dann wohl so:

$sql = "SELECT fid, namedt, nameor, regie, jahr, imdb, note,
anmerkung ";
$sql .= "FROM filme ";
$sql .= "WHERE namedt = " . $_POST['titel_dt'] . " AND nameor = " .
$_POST['titel_or'] " ";
$sql .= "ORDER BY namedt";

und so fort.

Wie generiere ich die richtige SQL-Abfrage für den jeweiligen
zutreffenden Fall?

Ich bedanke mich im Voraus für Tipps.

lf Günter

Re: Kriterien für Select durch Textfelder generieren lassen?

am 29.03.2007 17:21:07 von Irmgard Schwenteck

Hallo

Günter Thaler schrieb:

> // Angabe der Datenbank-Zugangsdaten

Das schreib mal in ein extra script und binde das mit include ein.
Es sei denn, es ist das allereinzigste Formular mit einer
Datenbankanbindung.

NIEMALS Formulareingaben ungeprüft übernehmen!

$titel=mysql_real_escape_string(trim($_POST['titel']));
$jahr=mysql_real_escape_string(trim($_POST['jahr']));

if ($titel != "") {
$stitel = "(namedt like '%".$titel."%')";
}
else {
$stitel = "(1=1)";
}
if ($jahr != "") {
$sjahr = "(jahr = ".$jahr.")";
}
else {
$sjahr = "(1=1)";
}

> $sql = "SELECT fid, namedt, nameor, regie, jahr, imdb, note,
> anmerkung FROM filme where ";
$sql .= $stitel ." AND ".$sjahr;

>
> Wie generiere ich die richtige SQL-Abfrage für den jeweiligen
> zutreffenden Fall?

Eine Abfrage mit 4 Variablen.

Analog kannst Du auch einen Suchtext für das Ergebnis zusammensetzen:
"Sie suchten nach Titel: foo, Jahr: 1988"

Gruß
Irmgard

Re: Kriterien fürSelect durch Textfelder generieren lassen?

am 29.03.2007 23:25:10 von Wolfgang Kueter

Günter Thaler wrote:

> [...]
> Wie generiere ich die richtige SQL-Abfrage für den jeweiligen
> zutreffenden Fall?

$sql = "SELECT ";
$sql .= "FROM filme ";
$sqlwhere = "WHERE ";
if ( isset ($_POST['titel_dt']) {
$sqlwhere .= "$_POST['titel_dt'] AND";
}
if (isset ($_POST['titel_dt'])) {
$sqlwhere .= "$_POST['titel_dt'] AND";
}
// und so weiter
wobei Du Dir noch überlegen solltest, was Du alles an Eingabefehlern
abfangen willst und ob das mit der Und-Verknüpfung der Kriterien wirklich
sinnvoll ist.

Die Suche wird bei 4 ausgefüllten Feldern, die Und-verknüpft sind sehr
scharf und viele User kriegen ein "Nix gefunden" obwohl sie sich nur beim
Jahr vertippt haben oder so. Weicher sind Suchen mit Like und auch über
Oder-Verknüpfungen solltest Du zumindest nachgedacht haben. Du brauchst
also eine Latte von Prüfungen, nach denen Dein Abfragestring zusammengebaut
wird. Befasse Dich also bitte ausgiebig mit Kontrollstrukturen ....

Wolfgang

Re: Kriterien für Select durch Textfelder generieren lassen?

am 30.03.2007 08:40:11 von g.thaler

Irmgard Schwenteck schrieb:

>
>> // Angabe der Datenbank-Zugangsdaten
>
> Das schreib mal [...]
Mach in normalerweise, danke dennoch.



> if ($titel != "") {
> $stitel = "(namedt like '%".$titel."%')";
> }
> else {
> $stitel = "(1=1)";
> }
> if ($jahr != "") {
> $sjahr = "(jahr = ".$jahr.")";
> }
> else {
> $sjahr = "(1=1)";
> }
>

OK, ich mache eine Verzweigung. Aber das da:

> else {
> $stitel = "(1=1)";

verswtehe ich nicht. -- Wenn der Anwender in das Feld nichts eingegeben
hat, dann soll der Wert von $stitel WAHR sein? ??

Kannst du mir das bitte noch beantworten? Jedenfalls danke.

lg Günter

Re: Kriterien für Select durch Textfelder generieren lassen?

am 30.03.2007 08:43:31 von g.thaler

Besten Dank auch dir für deine Antwort. Sehr klar.
Jetzt kann ich wieder weiter machen.

lg Günter

Re: Kriterien für Select durch Textfelder generieren lassen?

am 01.04.2007 13:53:46 von Martin Lemke

Günter Thaler schrieb:

> note
> anmerkung

Tipp am Rande.

Ich vermute, dass diese Felder nicht in jedem Datensatz belegt sind. Wenn
das so ist, solltest Du diese in separate Tabellen auslagern.

Martin

Re: Kriterien fürSelect durch Textfelder generieren lassen?

am 02.04.2007 23:08:20 von Wolfgang Kueter

Martin Lemke wrote:

>> [Tabelle mit 7 Feldern, davon manche NULL]
> Ich vermute, dass diese Felder nicht in jedem Datensatz belegt sind. Wenn
> das so ist, solltest Du diese in separate Tabellen auslagern.

Man kann es mit der Normalisierung auch übertreiben ...

Wolfgang

Re: Kriterien für Select durch Textfelder generieren lassen?

am 02.04.2007 23:09:39 von Claus Reibenstein

Wolfgang Kueter schrieb:

> Martin Lemke wrote:
>
>> Ich vermute, dass diese Felder nicht in jedem Datensatz belegt sind. Wenn
>> das so ist, solltest Du diese in separate Tabellen auslagern.
>
> Man kann es mit der Normalisierung auch übertreiben ...

Zumal dies (IMHO) mit Normalisierung nichts mehr zu tun hat ...

Gruß. Claus

Re: Kriterien fürSelect durch Textfelder generieren lassen?

am 03.04.2007 21:43:03 von Martin Lemke

Wolfgang Kueter schrieb:

> Man kann es mit der Normalisierung auch übertreiben ...

Natürlich sollte man nicht übertreiben und im Einzelfall Ausnahmen machen.

In diesem Falle, wo wahrscheinlich bei den meisten Datensätzen diese Felder
leer bleiben, halte ich es für opportun, separate Tabellen anzulegen.

Martin

Re: Kriterien für Select durch Textfelder generieren lassen?

am 03.04.2007 22:52:14 von Gregor Kofler

Irmgard Schwenteck meinte:

> dann muß die Variable $titel einen boolean Wert haben; TRUE oder FALSE
> halt. Leere Zeichenkette geht nicht.
> 1=1 ist true.
>
> Wolfgang hat Dir eine andere Variante gezeigt; dort muß man nur
> aufpassen, daß am Ende nicht ein "AND" in der Luft hängt.

IMO besser:

Die einschränkenden Klauseln in einem Array sammeln und diesen dann mit
AND imploden.

Gruß, Gregor


--
http://www.gregorkofler.at ::: Landschafts- und Reisefotografie
http://www.licht-blick.at ::: Forum für Multivisionsvorträge
http://www.image2d.com ::: Bildagentur für den alpinen Raum

Re: Kriterien für Select durch Textfelder generieren lassen?

am 03.04.2007 22:54:08 von Irmgard Schwenteck

Hallo

Günter Thaler schrieb:
>
>> if ($titel != "") {
>> $stitel = "(namedt like '%".$titel."%')";
>> }
>> else {
>> $stitel = "(1=1)";
>> }

>
> OK, ich mache eine Verzweigung. Aber das da:
>
> > else {
> > $stitel = "(1=1)";

Wenn man den SQL-String am Ende so zusammensetzt:
$sql .= $stitel ." AND ".$sjahr;

dann muß die Variable $titel einen boolean Wert haben; TRUE oder FALSE
halt. Leere Zeichenkette geht nicht.
1=1 ist true.

Wolfgang hat Dir eine andere Variante gezeigt; dort muß man nur
aufpassen, daß am Ende nicht ein "AND" in der Luft hängt.

In jedem Fall zum Testen die Variable $sql ausgeben lassen.

Gruß
Irmgard

Re: Kriterien fürSelect durch Textfelder generieren lassen?

am 03.04.2007 23:55:42 von Wolfgang Kueter

Irmgard Schwenteck wrote:


> Wolfgang hat Dir eine andere Variante gezeigt; dort muß man nur
> aufpassen, daß am Ende nicht ein "AND" in der Luft hängt.

Ich habe bewußt keine exakte Lösung des Problems gepostet, sondern wollte
dem OP nur mit einigen Beispielzeilen zeigen, in welche Richtungen er
nachdenken könnte/sollte. Der wesentliche Punkt dabei war, dass die Query
abhängig von den ausgefüllten Feldern zusammengesetzt wird. Dass die Query,
die dabei generiert wird, am Ende in jedem Fall syntaktisch korrektes SQL
sein muss, sollte eh klar sein. Um u.a. eben auch das sicherzustellen
existieren ja schließlich Kontrollstrukturen. ;)

Wolfgang