kostenloser Webspace werbefrei: lima-city


Suchalgorithmus

lima-cityForumProgrammiersprachenDelphi & Pascal

  1. Autor dieses Themas

    jacer

    Kostenloser Webspace von jacer

    jacer hat kostenlosen Webspace.

    Moin zusammen,

    ich hab ein kleines "logisches" Problem in einer kleinen Pascal-Software.

    Und zwar hab ich eine Suche in der ich 3 Angaben machen kann.
    Diese vergleiche ich Schritt für Schritt mit Datensätzen in einer Datenbank.

    Wenn dann die Angaben übereinstimmen, soll ein Eintrag hinzugefügt werden.

    Bisher habe ich es so gelöst, dass ich alle Angaben einzeln überprüft habe.
    Das hatte aber zur Folge, dass wenn Angabe 1 gestimmt hat, ein Eintrag inzugefügt wurde, und wenn Angabe 1+2 gestimmt haben, wurde noch ein Eintrag hinzugefügt. Ich hab also Datensätze doppelt.

    Ich habe versucht es über Schleifen zu machen bisher aber erfolglos.
    Ich möchte also eine Suche programmieren, mit 3 Suchfeldern.
    Man kann alle angeben, muss aber nicht und dass soll automatisch erkannt werden. Dann sollen die Datensätze der Datenbank danach überprüft werden.
    Ich hoffe ich konnte das einigermaßen verständlich erklären :wink:

    Ich brauche eigentlich nur den logischen Denkansatz weil ich gerade da nicht weiterkomme :slant:

    gruß
    jacer
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. also das Problem mit den Suchfeldern fängst du über die normale Verifizierung ab... wenn ein Feld den Wert "" hat, dann soll das ausgeschlossen werden.

    So, das weitere ist mir ein wenig schwammig formuliert...

    Was wird wo eingetragen?

    Welcher Art sind die Daten?

    Welches Volumen umfasst die Datenbank?

    und wie sollen die 3 Suchfelder aufeinander aufbauen, gleichzeitig erfüllt sein, oder mindestens eine der Bedingungen erfüllt sein?

    Beitrag zuletzt geändert: 27.10.2009 7:06:41 von sebulon
  4. burgi

    Co-Admin Kostenloser Webspace von burgi

    burgi hat kostenlosen Webspace.

    sebulon schrieb:
    Was wird wo eingetragen?

    Welcher Art sind die Daten?

    Welches Volumen umfasst die Datenbank?

    und wie sollen die 3 Suchfelder aufeinander aufbauen, gleichzeitig erfüllt sein, oder mindestens eine der Bedingungen erfüllt sein?

    Ich fände viel wichtiger, wie die Datenbankanbindung aussieht, denn wenn jacer die DB-VCL-Komponenten von Delphi nutzt, dann er die Suche vergessen, und das einfach über ein SQL-Query machen, da sich das in Delphi auf alle in TDataSet verwendbaren Datenbanken anwenden läßt! Dann wäre die Aufgabe nämlich so einfach: aus den 3 Suchbegriffen eine SQL-Abfrage, und gut ist. Wenn das Ergebnis leer ist, soll er einen Datensatz anlegen, und sonst nicht.
    Aber grundlegend hast du recht: etwas mehr Angaben dazu wären gut!

    jacer: dass, wenn ein Suchbegriff gefunden wird, bereits ein Datensatz angelegt wird, ist doch einfach zu umgehen, wenn ich mich nicht irre:
    Du kannst ja die Suche ruhig mit deinen Schleifen machen, allerdings würde ich nicht gleich beim Auffinden des ersten Sucharguments den Datensatz anlegen, sondern z.B. 3 Boolean-Werte setzen:
    //Suche
    //wenn Arg1 gefunden wird: Arg1 := True; (oder False)
    //wenn Arg2 gefunden wird: Arg2 := True; (oder False)
    //wenn Arg3 gefunden wird: Arg3 := True; (oder False)
    if Arg1 and (not Arg2) and (not Arg3) then
    begin
    //  Code, wenn Arg1 = True, Arg2 = False und Arg3 = False
    end
      else
          if Arg1 and Arg2 and (not Arg3) then
          begin
          //  Code, wenn Arg1 = True, Arg2 = True und Arg3 = False
          end
            else
    .
    .
    .

    Also erst auswerten, dann nachdenken, dann handeln :wink:
  5. Autor dieses Themas

    jacer

    Kostenloser Webspace von jacer

    jacer hat kostenlosen Webspace.

    Ok ich versuch es nochmal etwas genauer zu formulieren:

    Ich habe, wie bereits gesagt, 3 Suchangaben. Eins muss als minimum ausgefüllt sein.
    Sind allerdings mehrere ausgefüllt, sollen nur die Datensätze eine Aktion auslösen, in der alle Angaben übereinstimmen.

    Die Datenbank ist ne simple BDE und bisher hab ich es so gemacht, dass ich mit while table.eof do Schritt für Schritt die Datensätze durchgegangen bin und überprüft habe :slant:
  6. c****s

    Ich kann leider keine Pascal-Syntax, darum hier Pseudocode:
    if (argument1 is null and argument2 is null and argument3 is null) //falls alle leer sind
    	exit;
    query = "select foo from bar";
    where = "";
    if (argument1 is not null)
    	where = where + " baz='" + argument1 + "' and";
    if (argument2 is not null)
    	where = where + " baz='" + argument2 + "' and";
    if (argument3 is not null)
    	where = where + " baz='" + argument3 + "' and";
    where = leftstr (where, length (where) - 3); //letztes "and" abschneiden
    result = dbquery (query + " where " + where);
    dofunnystuff (result);


    Dieser Code halt sich alle Felder "foo" aus der Tabelle "bar", wo das Feld "baz" einem der drei Suchfelder entspricht.

    Beitrag zuletzt geändert: 27.10.2009 10:50:45 von census
  7. Autor dieses Themas

    jacer

    Kostenloser Webspace von jacer

    jacer hat kostenlosen Webspace.

    Ich versuchs einfach mal mit einem praktischeren Ansatz zu erläutern ich denke das bringt mehr :biggrin:

    Ich habe 3 Suchfelder: Name, Vorname, Wohnort (als Beispiel).

    Wie bereits gesagt muss ein Feld als minimum ausgefüllt sein.

    Im weiteren Code überprüfe ich dann ob die Felder ausgefüllt werdern, und setze eine Variable vom Typ Boolean dafür.
    Nennen wir sie hier jetzt einfach mal "vNameGefunden", "vVornameGefunden" und "vWohnortGefunden".

    Wenn ich über Schleifen gehe muss ich also anschließend alle Möglichkeiten durchgehen.
    D.h. ob nur der Name, nur der Vorname oder nur der Wohnort in einem Datensatz übereinstimmen.
    Oder ob Name und Wohnort, Vorname und Wohnort oder sogar alle 3 stimmen.

    Und genau da liegt mein Problem. Ich bekomme keine Schleifen-Anweisung hin, in der ich alle Möglichkeiten überprüfe, so dass am Ende wenn einer der Möglichkeiten stimmt, eine Aktion ausgeführt wird.

    Ich hoffe das war deutlicher jetzt :wink:
  8. burgi

    Co-Admin Kostenloser Webspace von burgi

    burgi hat kostenlosen Webspace.

    jacer schrieb:
    Die Datenbank ist ne simple BDE und bisher hab ich es so gemacht, dass ich mit while table.eof do Schritt für Schritt die Datensätze durchgegangen bin und überprüft habe :slant:

    Genau deswegen würde ich den Weg über eine Abfrage lösen, was sicher auch performanter ist. Dann brauchst du in der Schleife nur die betreffenden Einträge durchgehen, und die Aktionen damit ausführen, die du denen angedacht hast. Wenn das Ergebnis leer wäre, dann heißt das, dass keines der Suchargumente gefunden wurde.

    @census: :megarofl:
    if (argument3 is not null)
    	where = where + " baz='" + argument3 + "' and";
    where = leftstr (where, length (where) - 3); //letztes "and" abschneiden

    wäre das dann nicht einfacher so: :confused:
    if (argument3 is not null)
    	where = where + " baz='" + argument3;

    Aber egal, der Grundgedanke ist der selbe, wie ich sagte mit der SQL-Abfrage über das TDataSet.

    jacer: kannst du das Delphi-Projekt irgendwo bereitstellen (vorausgesetzt, es ist nichts drinnen, was "schützenswert" wäre)? Du Oder kannst du einen Screenshot vom Formular hochladen, irgendwas, was die verwendeten Komponenten zeigt, und die Zusammenhänge zwischen denen? Das würde eine ordentliche Erklärung wesentlich erleichtern, so müssen wir gewisse Sachen annehmen oder erraten, was nicht recht zielführend ist ...

    Mensch, schon wieder ein neuer Beitrag :biggrin:
    So wie du es jetzt erklärt hast, musst du einfach in der Abfrage anstelle des "and" ein "or" benutzen, das sollte das sein, was du haben willst. Eine Schleife ist dafür auch nicht das geeignete Werkzeug. Wenn schon mit Schleife, dann darfst du nicht die 3 Sachen nacheinander prüfen, sondern mußt alle 3(!) Kriterien als Abbruchkriterien für die Schleife benützen!
  9. Es gibt bei den Borland-Buildern so ein Modul, das Heißt SQL-Query... das dürfte Datenbank unabhängig sein... also mit Delphi und C++ habe ich damit gearbeitet und es lief... ich hatte auch einfache Datenbanken, was die BDE zur verfügung stellte genommen... hab mich meist für eine Paradox 7 Tabelle entschieden... und da funktionierte dieses SQL-Query-Modul... Die Datenbank rufst du ja mit TDataSheet auf, nicht war?

    Edit: ist zwar ne Weile her bei mir, aber ich kann mich entsinnen, dass es noch so ein struct-Modul gab, was benötigt wurde, um SQL auszuführen... hatte es allerdings nur bei datenbanken bis 100000 DS im Einsatz, lief aber trotzdem recht flott...

    Beitrag zuletzt geändert: 27.10.2009 11:24:52 von sebulon
  10. c****s

    burgi schrieb:
    @census: :megarofl:
    if (argument3 is not null)
    	where = where + " baz='" + argument3 + "' and";
    where = leftstr (where, length (where) - 3); //letztes "and" abschneiden

    wäre das dann nicht einfacher so: :confused:
    if (argument3 is not null)
    	where = where + " baz='" + argument3;


    Nein. Dann läuft der Code nämlich ins Nirvana, wenn z.B. argument1 und argument2 gesetzt sind, aber nicht argument3. Durch meinen Ansatz weiß ich, dass egal ob 1 oder 2 oder 3 Argumente gesetzt sind (und auch egal welche davon), das statement immer auf "and" endet.
    Zur Veranschaulichung ein Beispiel:
    Seien argument1 = null, argument2 = "zweiundvierzig" und argument3 = null.
    Bei meinem Ansatz heißt die query dann
    select foo from bar where baz='zweiundvierzig'

    Bei deinem Ansatz heißt die query dann
    select foo from bar where baz='zweiundvierzig' and

    Das Problem ist, das man im Vorfeld nicht weiß, welche der 3 Argumente gesetzt sind.
  11. Autor dieses Themas

    jacer

    Kostenloser Webspace von jacer

    jacer hat kostenlosen Webspace.

    Also erstmal Danke der Ansatz von Census bringt mich auf alle Fälle eine ganze Ecke weiter...

    Ich hab immer eine Lösung in Pascal gesucht anstatt es einfach über die Abfrage zu regeln.

    Nun hab ich nur noch ein kleines Problem. Eines der Felder die überprüft werden ist ein Datum.
    Hier soll aber nicht nur auf das exakte Datum geprüft werden, sondern auf einen Zeitraum zwischen 2 Daten (2 einzelne Datensätze in der Datenbank).

    Kann ich dann in der SQL-Abfrage auch einfach mit >= etc arbeiten?
    Oder wie löse ich das?

    Beitrag zuletzt geändert: 27.10.2009 13:18:25 von jacer
  12. c****s

    Nehmen wir mal an coitus wäre vom Typ timestamp:

    select partner from sexualintercourse where coitus > '2009-01-01 13:40:20' and coitus < '2010-01-01 14:30:20'
  13. Autor dieses Themas

    jacer

    Kostenloser Webspace von jacer

    jacer hat kostenlosen Webspace.

    census schrieb:
    Nehmen wir mal an coitus wäre vom Typ timestamp:

    select partner from sexualintercourse where coitus > '2009-01-01 13:40:20' and coitus < '2010-01-01 14:30:20'



    Und wenn wir annehmen, ich habe 2 Daten als String im Format 01.01.2000 ...

    Lassen die sich auch ohne Umstände so vergleichen?
  14. burgi

    Co-Admin Kostenloser Webspace von burgi

    burgi hat kostenlosen Webspace.

    jacer schrieb:
    Und wenn wir annehmen, ich habe 2 Daten als String im Format 01.01.2000 ...

    Lassen die sich auch ohne Umstände so vergleichen?

    Ich denke nicht, dass das mit einem String ebenfalls so einfach funktioniert.

    [Dudu-Finger heb]
    Man legt aber Zeitangaben auch nicht als String ab!
    [Dudu-Finger senk]
  15. burgi schrieb:
    jacer schrieb:
    Und wenn wir annehmen, ich habe 2 Daten als String im Format 01.01.2000 ...

    Lassen die sich auch ohne Umstände so vergleichen?

    Ich denke nicht, dass das mit einem String ebenfalls so einfach funktioniert.

    [Dudu-Finger heb]
    Man legt aber Zeitangaben auch nicht als String ab!
    [Dudu-Finger senk]


    Genau!!!

    als richtiger PowerUser legt man seine Uhrzeitangaben als integer ab... als Zahl der Sekunden seit dem Jahr 1970... mit der Geburt von UNIX^^
  16. Autor dieses Themas

    jacer

    Kostenloser Webspace von jacer

    jacer hat kostenlosen Webspace.

    Habe es getestet und sofern beide Datumswerte das gleiche Format haben (in meinem Fall DD.MM.YYYY) lassen sie sich auch als String über normale Vergleichsoperatoren vergleichen.

    Hätte damit mein Problem gelöst :thumb:

    Danke für die Hilfe...
  17. c****s

    jacer schrieb:
    Habe es getestet und sofern beide Datumswerte das gleiche Format haben (in meinem Fall DD.MM.YYYY) lassen sie sich auch als String über normale Vergleichsoperatoren vergleichen.

    Hätte damit mein Problem gelöst :thumb:

    Danke für die Hilfe...


    oO, glaub ich nicht. Hast du exemplarisch ein paar Daten miteinander verglichen oder kannst du wirklich mit Sicherheit sagen, dass der Stringvergleich funktioniert? Im Format "YYYY-MM-DD" würde (bei Standardkollation) das hinhauen, aber nicht bei "DD.MM.YYYY":

    Ein Paar Beispiele zur Verdeutlichung (utf-8 collation):
    "02.01.2009" > "01.02.2009" weil 2 nach 1 kommt.
    "02.01.2008" > "01.02.2009" weil 2 nach 1 kommt.
  18. Autor dieses Themas

    jacer

    Kostenloser Webspace von jacer

    jacer hat kostenlosen Webspace.

    Ja leider hat die Variante doch noch Fehler ergeben.
    Damit steh ich wieder vor dem gleichen Problem. Die zu vergleichenden Daten sind als String in einer Datenbank gespeichert und ich benötige sie in der SELECT-Anweisung...

    Edit: Also muss ich die Datumswerte auslesen in ein TDate-Format umwandeln und überprüfen? Das hieße ja, dass wenn in der Suche ein Datum verwendet wird, ich über die SELECT-Anweisung alle Datensätze auslesen und einzeln überprüfen muss. Oder hab ich noch eine andere Möglichkeit?

    Beitrag zuletzt geändert: 28.10.2009 12:12:47 von jacer
  19. c****s

    jacer schrieb:
    Edit: Also muss ich die Datumswerte auslesen in ein TDate-Format umwandeln und überprüfen? Das hieße ja, dass wenn in der Suche ein Datum verwendet wird, ich über die SELECT-Anweisung alle Datensätze auslesen und einzeln überprüfen muss. Oder hab ich noch eine andere Möglichkeit?


    Das wäre die Holzhammermethode. In Abhängigkeit von deinem DBMS gibt es verschiedene Convert-Funktionen. Welche genau musst du nachlesen, da ich nicht weiß welches DBMS in welcher Version du nutzt. Der Code sähe dann irgendwie so ähnlich aus:

    Wir nehmen an coitus wäre ein String, der ein Datum enthält:
    SELECT partner FROM sexualintercourse where CONVERT(TIMESTAMP,coitus) > CONVERT(TIMESTAMP,'2009-12-08 20:45:67GMT+1*)
  20. Autor dieses Themas

    jacer

    Kostenloser Webspace von jacer

    jacer hat kostenlosen Webspace.

    Als bei der Convert-Variante traten immer wieder Fehler auf.

    Habe jetzt über

    CAST(Datum as DATE)


    gearbeitet und es funktioniert einwandfrei :wink:

    Beitrag zuletzt geändert: 28.10.2009 14:47:04 von jacer
  21. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!