Beitrag von Frank (474 Beiträge) am Montag, 17.August.2009, 18:39.
Dokubeispiele zu ~= und query
Das Beispiel aus der Doku
http://doku.baseportal.de/48.html
hier abgebildet:
get ["Name", "==!", "Stefan Klamm", "&", "URL", "==", $URL], "zugriffe";
habe ich folgendermaßen abgeändert, bekomme aber keine Ausgabe, -warum?
get ["PLZ", "~=", "5", "&", "Flaeche", ">", "100"], "Eifelraum";
while(get_next("Eifelraum"))
{
out "PLZ: $PLZ, Ort: $Ort, Seite: $Page<br><br>";
}
Es müsste 1 Eintrag aus der datenbank kommen, die Ausgabe müsste sein:
PLZ: 53909, Ort; Zülpich, Seite; Zülpich Stadt
Versuche mit == funktionieren, natürlich nur dann, wenn ich die gesamte Postleitzahl eingebe, aber es soll nach Postleitzahlbereichen gesucht werden können.
Das Beispiel in der Doku, selbe Seite
my @query;
for(my $i=0; $i<21; $i+=3)
{
push @query, "Wert", "==", $i, "|";
}
get \@query, "datenbank";
habe ich testweise so umgesetzt:
my @query;
for(my $i=0; $i>100; $i+=10)
{
push @query, "Flaeche", "==", $i, "|";
}
get \@query, "Eifelraum";
while(get_next("Eifelraum"))
{
out "PLZ: $PLZ<br> Ort: $Ort<br><br><hr width='30%' align='left'";
}
Als Ausgabe bekomme ich nun soviele 'hr-Bereiche' wie Datensätze in der Datenbank vorhanden sind. Einer davon ist mit Daten gefüllt, nämlich der, der im Feld 'Flaeche' 140 eingetragen hat. Nun müsste man mit sowas wie 'if >0' hantieren, oder gibt es eine einfachere Form die leeren Datensätze gar nicht erst auszugeben?
Antworten
Beitrag von Sander (8133 Beiträge) am Montag, 17.August.2009, 20:07.
Re: Dokubeispiele zu ~= und query
hast du eventuell plz nach Zahl sortiert? muß text sein...
Antworten
Beitrag von Frank (474 Beiträge) am Dienstag, 18.August.2009, 07:51.
Re: Re: Dokubeispiele zu ~= und query
Ja, tatsächlich, aber wieso denn? Also darauf wäre ich jetzt nicht gekommen. Wozu dient dann die Sortierung nach Zahl? Vielen Dank für die schnelle Antwort.
Antworten
Beitrag von Frank (474 Beiträge) am Dienstag, 18.August.2009, 07:57.
Re: Re: Dokubeispiele zu ~= und query
Ich habe das Feld PLZ als 'Zahl'-Feld deklariert mit dem höchsten Wert 99999 und 'Sortierung' ausgewählt.
Antworten
Beitrag von richard (1187 Beiträge) am Dienstag, 18.August.2009, 09:08. WWW: posaunenchor-rhoden.de
Re: Re: Dokubeispiele zu ~= und query
Was Sander wohl meinte war, daß man Zahlen nicht immer wie Texte abfragen kann.
Das Plz-Feld sollte also vom Typ Text sein, bin mir im Moment aber nicht sicher ob es unter bp auch als Text sortiert sein muß.
Antworten
Beitrag von Sander (8133 Beiträge) am Dienstag, 18.August.2009, 11:39.
Re: Re: Re: Dokubeispiele zu ~= und query
Antworten
Beitrag von richard (1187 Beiträge) am Dienstag, 18.August.2009, 09:46. WWW: posaunenchor-rhoden.de
Re: Re: Dokubeispiele zu ~= und query
Was Dir vielleicht auch weiterhilft.
Zahlen kann man sinnvoll so abfragen:
plz>=50000
Antworten
Beitrag von Pouraga (1396 Beiträge) am Dienstag, 18.August.2009, 10:52.
Re: Re: Re: Dokubeispiele zu ~= und query
Weil man Zahlen nicht auf Anfang abfragen kann! Das ist so, weil das technisch keinen Sinn macht. Die ersten Zeichen einer "Zahl" haben nichts mit ihrer Position im index zu tun.
Sortierung nach Zahl
78
610
1616
6026
Sortierung nach Text
1616
6026
610
78
Antworten
Beitrag von Pouraga (1396 Beiträge) am Dienstag, 18.August.2009, 11:31.
Re: Dokubeispiele zu query
Antworten
Beitrag von Frank (474 Beiträge) am Dienstag, 18.August.2009, 13:34.
Re: Re: Dokubeispiele zu query
Speziell im Fall query habe ich nichts weiter vor. Aber als ein voriges Beispiel aus der Doku nicht funktionierte (wg Zahlfeld statt Textfeld) habe ich natürlich erstmal alles überprüft, was dort als Beispiel angezeigt ist, und nun bin ich wieder etwas schlauer.
Woran ich tatsächlich tüftele ist ein Abfrageformuar für die Datenbank in dem ich aus Checkboxen, Optionsfeldern und Textfeldern mit 'und'-, oder 'oder'- Verknüpfungen perfektere Ergebnisse erziehlen kann. Zunächst wäre ich schon einen Schritt weiter, wenn mir das mit einer Verknüpfungsart gelingen würde. Die Krönung wäre natürlich mit Klammerungen beide Verknüpfungen in eine Suche packen zu können, aber wie bloß - über ein Formular? Ich muß dazu sagen, daß in meinem CMS die Möglichkeiten von do...etc nicht gegeben sind, es geht nur do_all, aber es soll nicht alles ausgegeben werden, doch die Einschränkungen mit listfields und allfields, formfields usw. funktionieren hier nicht. Deshalb also eine Eigenproggy mit get.
Eigentlich hatte ich gehofft, daß das Script Inndexsuche von Fehde aus der Bib funktioniert, aber es kommt kein Ergebnis, was durchaus auch an der Programmierung des CMS4free liegen kann, welches ich als Grundlage verwende. Allein sein Anhängsel &bei123, das ich in &raum gewandelt habe, hat richtig Arbeit gemacht, ob es nötig ist? Ich weiß es nicht. Im [Text]feld läßt sich jedenfalls auch Perlcode eintragen und damit das ganze Script auch dann noch funktioniert beginnt man Perlcode mit EOF und schließt mit out<<EOF; ab - damit wird vielleicht ein bischen klarer, wie das Script CMS4free aufgebaut ist. Hier kann ich also auch Scripte aus der Bib nach Anpassung eintragen. Bei Indexsuche ist aber nach
<form action=" http://de3.arteurope.de/cgi-bin/baseportal.pl?htx=$htx&raum=1,7,9" method="post" enctype="multipart/form-data">
<input type="text" name="Such=" size="15" value>
<input type="submit" value="Suchen">
</form>
EOF
if ($Such ne "") #---------------------falls eine Suchanfrage gestartet wurde
#---------------- und das Eingabefeld [Such] nicht leer ist
{
out "Suchbegriff =<b>[$Such]</b><br>";
my $i=0;
erstmal Schluß. Hier wird der Suchbegriff ausgegeben und Treffer=0. So geht es weiter:
get "Id==*","Eifelraum";
while(get_next)
#----------- gesucht wird in dem Feld [Text] -------------------------------
{if ((index($Page,$Such) >= 0 ))
{$i++;
$Daten[$i]="$i.<a href='http://arteurope.de/cgi-bin/baseportal.pl?
htx=$htx&raum&Id==$_id'>$Page</a><br>";
#----------- als Link wird das Feld [Titel] ausgegeben ----------------------
}
my $y=1;
while ($y < $i+1){out $Daten[$y];
$y++ ;}
}
"";
out<<EOF;
So eine richtige Lösung, wenn es denn funktionieren würde, ist das aber nicht. Eigentlich geht es um spezialisierte Abfragen, so wie es in SQL einfach zu tätigen wäre:
SELECT * FROM Eifelraum WHERE Ort="Zülpich" AND Flaeche="140" OR Ort="Euskirchen" AND Flaeche="140";
Antworten
Beitrag von Sander (8133 Beiträge) am Dienstag, 18.August.2009, 13:52.
Re: Re: Re: Dokubeispiele zu query
deine query geht schnell umzusetzen:
Ort==Zülpich|Ort==Euskirchen&Flaeche=140
schwierig wirds, wenn du verschiedene flächen und orte abfragen wölltest.
das geht nur über mehrere get's - leider.
ich frag dann jede klammerung eigenständig ab und füge sie zu einem hash zusammen. den geb ich dann als ergebnis aus. leider mußt du dann immer alle holen und das blättern muß auch geproggt werden.
Antworten
Beitrag von Frank (474 Beiträge) am Dienstag, 18.August.2009, 16:41.
Re: Re: Re: Re: Dokubeispiele zu query
Das ist eigentlich auch das erste mal, daß ich mir hier "freihändig" etwas selbst programmiere, bisher habe ich immer nur Scripte angepasst. Und natürlich liegt der Teufel im Detail.
Ich habe jetzt als Beispiel
out <<EOF;
<form action="baseportal.pl?htx=/$htx" method="post" enctype="multipart/form-data">
<input type="hidden" name="htx=" value="$htx">
<p>Kreuzen Sie die gewünschten Eigenschaften an:</p>
<p>
<input type='checkbox' name='Parken' value=''>Parkmöglichkeit<br>
<input type='checkbox' name='Lagern' value=''>Lagermöglichkeit <br>
<input type='checkbox' name='Verwahren' value=''>gesicherte Unterstellung/Verwahrung
<input type='submit' name='Search' value='Suchi'>
</p>
</form>
EOF
out $Lagern;
if ($Lagern ne "")
{
get ["Lagern", "==","$Lagern"], "Eifelraum";
while(get_next("Eifelraum")){
out "PLZ: $PLZ, Ort: $Ort, Seite: $Page<br>";
}
}
</perl>
Es soll in diesem Beispiel nur verglichen werden, ob Lagern angekreutzt ist und wenn ja, sollen alle Datensätze aus der Datenbank, die diesen Wert haben ausgegeben werden. Die Variable $Lagern gibt aber gar nichts her, sie ist leer, warum?
Antworten
Beitrag von richard (1187 Beiträge) am Dienstag, 18.August.2009, 17:27. WWW: posaunenchor-rhoden.de
Re: Re: Re: Re: Re: Dokubeispiele zu query
Dürfte an dem " value='' " liegen. Solltest Du vollständig herausnehmen.
Vorbelegen kann man checkboxen mit "checked" bzw. "checked=checked".
Markierte checkboxen fragt man nach "on" ab.
Wie das dann mit Deinen Felder verglichen werden muß hängt eventuell von Deiner Felddefinition ab.
Antworten
Beitrag von Sander (8133 Beiträge) am Dienstag, 18.August.2009, 21:02.
Re: Re: Re: Re: Re: Dokubeispiele zu query
Antworten
Beitrag von richard (1187 Beiträge) am Dienstag, 18.August.2009, 23:38. WWW: posaunenchor-rhoden.de
Re: Re: Re: Re: Re: Re: Dokubeispiele zu query
Antworten
Beitrag von Sander (8133 Beiträge) am Mittwoch, 19.August.2009, 00:41.
Re: Re: Re: Re: Re: Re: Re: Dokubeispiele zu query
er braucht das schon - außer er verwendet method=get ohne multípart/form-data
ansonsten reagiert baseportal nicht auf die übergebenen Vars und stellt sie intern nicht bereit.
Antworten
Beitrag von Friesecke (245 Beiträge) am Dienstag, 18.August.2009, 21:08.
Re: Re: Re: Re: Dokubeispiele zu query
Hallo Sander,
nenn mal ein Beispiel fuer "jede klammerung"
Vielleicht hab ich Dich nicht richtig verstanden, aber vielleicht geht das doch mit nem einzelnen get
Gruss
Friesecke
Antworten
Beitrag von Sander (8133 Beiträge) am Dienstag, 18.August.2009, 21:30.
Re: Re: Re: Re: Re: Dokubeispiele zu query
Antworten
Beitrag von Frank (474 Beiträge) am Mittwoch, 19.August.2009, 16:59.
Re: Re: Re: Re: Re: Re: Dokubeispiele zu query
Ich bin nun soweit gekommen:
<form ...
<select name="Region" size="3" multiple>
<option>Voreifel</option>
<option>Hohes Venn</option>
<option>Nordeifeifel</option>
</select><br/>
...</form>
if ($Region ne ""){
get Id==["Region", "==","$Region"], "Eifelraum", "region";
get "$Region==$region", "Eifelraum";
while(get_next("Eifelraum")){
out "$Region $PLZ $Ort\n\n";
}
} else
{
undef(%_get);
}
Und nun bekomme ich, nachdem ich im Formular eine Region gewählt habe, alle Datensätze, in der das Feld Region belegt ist, das soll aber nicht sein. Beispielsweise sollen nach der Wahl 'Voreifel' nur die Id der Datensätze, die in ihrem Feld namens 'Region' dann auch 'Voreifel' eingetragen haben im hash gespeichert werden.
Im Weiteren möchte ich dann (später) andere Eigenschaften in separate hashs speichern und schließlich die Schnitmenge ausgeben.
Antworten
Beitrag von Sander (8133 Beiträge) am Mittwoch, 19.August.2009, 21:13.
Re: Re: Re: Re: Re: Re: Re: Dokubeispiele zu query
auch hier muß bei post und enctype=multipart/form-data ein = an region im form
<select name="Region=" size="3" multiple>
multiple sind in bp aber vorher noch zu behandeln, da sie als ein string rüber kommen:
@regionen=split/\n/,$Region;
foreach(@regionen){
push @where,"Region==$_";
}
$where=join"|",@where;
get $where,"Eifelraum";
...
dein
get Id==["Region", "==","$Region"], "Eifelraum", "region";
ist falsch (Id==Region==$Region). Wenn mit Array gearbeitet werden soll, dann
get ["Region", "==","$Region"], "Eifelraum", "region";
dann passt das $where aber nicht da rein ;)
Antworten
Beitrag von Friesecke (245 Beiträge) am Mittwoch, 19.August.2009, 17:18.
Re: Re: Re: Re: Re: Re: Dokubeispiele zu query
Antworten
Beitrag von Frank (474 Beiträge) am Donnerstag, 20.August.2009, 18:20.
Re: Re: Re: Re: Re: Re: Re: Dokubeispiele zu query
Das eigentliche Problem scheint mir nun zu sein wie man aus den separierten Datensätzen durch weitere Abfragen Teilmengen "herausprügelt".
Die o.g. Lösungsansätze funktionieren für das, was sie darstellen, wenn ich dies nun mit zusätzlichen Checkboxabfragen zusammenbringe, entsteht für mich wieder ein riesen Problem.
$csParken="1" if $Parken ;
out<<EOF;
<form action="baseportal.pl?htx=$htx&cmd=search" method="post" enctype="multipart/form-data">
<select name="Region=" size="3" multiple>
<option>Voreifel</option>
<option>Hohes_Venn</option>
<option>Nordeifel</option>
</select><br/>
<input type='checkbox' name="Parken=" value='' $csParken>Parkplatz<br>
<input class=submit type=submit value="Abschicken"> </form>
EOF
@regionen=split/\n/,$Region;
foreach(@regionen){
push @where,"Region==$_";
}
$where=join"|",@where;
get "$where","Eifelraum","all";
while(get_next("all")){
$Id_all=$Id;
}
Damit sind jetzt alle Datensatz-'Id's, die über das Optionalfeld Region ausgewählt wurden in der Variable $Id_all, -prima. Setzen wir das genauso fort und versuchen nun die Checkbox mit einzubeziehen, die die bisher gefundenen Datensätze weiter filtern soll. Wir wollen nur die mit Parkplatz.
@Id_all=split/\n/,$Id_all;
foreach(@Id_all){
push @reg,"Id==$reg & Parken==$Parken";
}
$reg=join"|",@reg;
get "$reg", "Eifelraum";
while(get_next("Eifelraum")){
out "$PLZ $Ort $Raumname <a href='#'>$Page</a><br><br>";
}
Das Id==$reg taugt nicht, die Werte liegen zwar getrennt, aber dennoch alle in $reg und werden nicht etwa einzeln ausgetauscht. Es kommen also nicht alle Einträge, die nun die richtige Region besitzen und einen Parkplatz haben, sondern es kommt nur der erste gefundene Eintrag.
Ich habe dann rumexperimentiert mit:
@regionen=split/\n/,$Region;
foreach(@regionen){
push @where,"Region==$_";
}
$where=join"|",@where;
get "$where","Eifelraum","all";
while(get_next("all")){
$Id_all=$Id;
}
%idx=($Id_all);
Hier packe ich den String in einen assoziativen Array %idx, mit dessen Hilfe ich dann auf die einzelnen Elemente zugreifen kann. Aber ich brauche auch noch was zum hochzählen.
my @query;
for(my $i=0; $i+=1; $i<800)
{
push @query,"Id==$idx[$i] & Parken==$Parken";
}
$query=join"|",@query;
Und ob das bis hier stimmt würde ich gerne erfahren. Es kommt immer eine Fehlermeldung, die sich eigentlich nur auf diesen Teil beziehen kann, denn der Rest ist nur noch die Ausgabe:
get "$query", "Eifelraum";
while(get_next("Eifelraum")){
out "$PLZ $Ort $Raumname <a href='#'>$Page $Id</a>";
}
Antworten
Beitrag von Frank (474 Beiträge) am Freitag, 21.August.2009, 22:06.
Re: Re: Re: Re: Re: Re: Re: Re: Dokubeispiele zu query
PERL IST GROß
Das Zauberwort heißt "Interselect"
sue strict;
use Data::Dumper;
my @array1 = (1, 2, 3);
my @array2 = (2, 3, 4);
my %array1 = map{$_ =>1} @array1;
@isect = grep ( $array1{$_}, @array2 );
print Dumper(\@isect);
Sanders Beitrag hat mich auf die richtige Fährte gebracht.
Da wirkt mein neues Problem eher wie ein Problemchen.
Über Interselect erreiche ich eine Ausfilterung, z.B. über Checkboxen, Optionsfelder usw. Wird aber ein Filter nicht betätigt, müssen alle Id geholt werden - und das für jede Abfrage. Das wäre eigentlich nicht notwendig, denn es handelt sich ja nur um eine Zahlenliste.
Meine Idee war die Id der Datensätze einmal zu holen in einem Array zu speichern und dies dann in der if-Schleife hinter 'else' zu referenzieren.
Also zuerst z.B.
get "Raumname<>_", "Eifelraum";
while(get_next("Eifelraum")){
push @NRW,"$Id";
}
und nun genau den Teil nach else
if ($PLZx ne ""){
get "PLZ~=$PLZx", "Eifelraum", "plz";
while(get_next("plz")){
push @array2,"$Id";
}
} else
{
get "Raumname<>_","Eifelraum","all";
while(get_next("all")){
push @array2,"$Id";
}
}
mit dem Array @NRW austauschen. Aufgrund der hochflexiblen Struktur muß jeder Filter seinen eigenen Namen behalten, hier also @array2. Meine Frage,
wie bekomme ich jetzt den Inhalt von @NRW in @array2, bzw wie kann ich @NRW in @array2 umbenennen?
Ich bin vieleicht für heute so platt programmiert, daß ich einfach nicht auf die Lösung komme. Es würde nämlch einiges an Geschwindigkeit gewonnen werden können. Bei 10 bis 20 Filtern und nehmen wir mal 500 Datensätze an, kommt da schon einiges an Zeit zusammen. Wenn man bedenkt, daß normale Anfragen an den Baseportal-Server in 0,02 Sekunden erledigt werden, scheint das erstmal nicht so tragisch. Und dennoch, es ist ja nicht nur Sport sondern auch Ausdruck einer guten Programmierung, wenn man immer den schnellsten Weg findet. In dem Sinne
PERL IST GROß
macht aber viel Arbeit
(dafür aber keinen Dreck)
Antworten
Beitrag von Sander (8133 Beiträge) am Freitag, 21.August.2009, 22:20.
Re: Re: Re: Re: Re: Re: Re: Re: Re: Dokubeispiele zu query
Antworten
Beitrag von frank (8 Beiträge) am Samstag, 22.August.2009, 09:59.
Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Dokubeispiele zu query
Jetzt machst du es dir aber einfach - und funktionieren tut es nicht:
get "Raumname<>_", "Eifelraum";
while(get_next("Eifelraum")){
push @NRW,"$Id";
}
@array1=@NRW;
#Nach folgender Schleife wird der Inhalt von @NRW in rot ausgegeben.
$I=0;
while ($i <= $#NRW) {
out "<font color='red'>$NRW[$i++]</font>", "\n\n";
}
#Die Ausgabe für @array1 sollte in blau kommen, kommt aber nicht, weil offensichtlich keine Elemente vorhanden sind.
$I=0;
while ($i <= $#array1) {
out "<font color='blue'>$array1[$i++]</font>", "\n\n";
}
Nun erfolgt ja die Ausgabe eines @array über $array aber auch Konstrukte wie:
oder etwa
$I=0;
while ($i <= $#NRW) {
push @array1,"$NRW[$i++]";
}
bringen nicht den gewünschten Erfolg.
Antworten
Beitrag von Sander (8133 Beiträge) am Samstag, 22.August.2009, 13:12.
Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Dokubeispiele zu query
da haste wohl einen käfer drin - weil so funktioniert definitiv das kopieren.
http://baseportal.de/cgi-bin/baseportal.pl?htx=/sander/test_2
und der Quelltext:
http://baseportal.de/cgi-bin/baseportal.pl?show=/sander/test_2
statt dem großen Konstrukt zur Kontrolle
$I=0;
while ($i <= $#NRW) {
out "<font color='red'>$NRW[$i++]</font>", "\n\n";
}
kannst du in bp ein
oder generell in Perl ein
out "<font color='red'>$_</font>" foreach(@NRW);
oder bei ner Liste (so wie ich)
out "<font color=red>@NRW</font><br>";
machen.
die Länge einer Liste ermittelt man mit
out $laenge=@NRW;
nicht das deine Schleife falsch wäre aber gebräuchlicher ist dann
$i=0;
while ($i < @NRW) {
out "<font color='red'>$NRW[$i++]</font>", "\n\n";
}
bzw
for($i=0;$i<@NRW;$i++)
out "<font color='red'>$NRW[$i++]</font>", "\n\n";
}
und da seh ich auch gerade deinen Bug:
du schreibst
$I=0;
machst in der Schleife aber mit $i weiter. Die Vars sind case sensetive
bei der ersten schleife klappt das, da $i nicht vorhanden, also 0 war.
in der 2ten hat $i aber den Wert von @NRW - @array1 hat da aber keine Elemente mehr. also wird nix ausgegeben.
Antworten