none
Datenabfrage auf DataTable Problem RRS feed

  • Frage

  • Hallo Leute ich stehe total auf dem schlauch, und zweifele gerade an meine Denklogik.

    Ich habe eine DataTable mit folgenden Einträgen

    RecNo | Kdnr | Datum        | Suchfeld
           1         3   01.01.2011   KLMD
           3         5   02.01.2011   KLMD
           7         3   10.01.2011   MDFR
         10         7   10.01.2011   TREF
         11         9   10.01.2011   KLMD
         17         3   20.01.2011   TREF

    Nun versuche ich über die DataTable.Select(Datum>='01.01.2011' AND Datum<='20.01.2011' AND Suchfeld Like 'KLMD*' AND NOT Suchfeld Like 'TREF*')  die Abfrage zu starten

    Ich bekomme immer Kunde 3 Angezeigt der zwar die erste Bedingung erfüllt "KLMD" ist vorhanden, aber die zweite Bedingung nicht erfüllt "TREF" soll er nicht haben.

    Wer gibt mit nachhilfe in Abfragen wäre wirklich sehr dankbar.

    Gruß Thomas

     

    Dienstag, 28. Juni 2011 10:28

Antworten

  • Hi Markus,
     
    Wenn du das Selektieren über mehrere verschiedene Selectmethoden fest codieren kannst dann geht natürlich auch Linq.
     
    Eine Linq Anweisung muss nicht fest programmiert sein. Bei variablen Anforderungen kann man Expression Tress nutzen und damit dynamisch Abfragen “zusammenbasteln”.
     
    Oder auch eine While Schleife, die vermutlich besser zu verstehen ist.
     
    Das ist nur eine Frage der Linq-Kenntnisse. Ich finde, dass Linq viel übersichtlicher ist, da die Abfrage kompakter nur an einer Stelle definiert wird anstelle einzelner Codezeilen in ggf. langen Code-Schleifen.
     
    --
    Viele Grüße
    Peter
    • Als Antwort markiert tommytom73 Mittwoch, 13. Juli 2011 09:17
    Dienstag, 5. Juli 2011 03:40

Alle Antworten

  • Deine Abfrage ergibt als Ergebnis eine Menge aus drei Datensätzen, und zwar RecNo=1, 3 und 11.
     
    Du fragst: Gib mir bitte alle Datensätze, die das Datum vom '01.01.2011' bis zum '20.01.2011' haben UND das Suchfeld mit 'KLMD' beginnt UND das Suchfeld nicht mit 'TREF' beginnt. Das trifft beim Datensatz mit RecNo=1 zu.
     
    Was willst Du genau haben?
     
    --
    Viele Grüße
    Peter

    Dienstag, 28. Juni 2011 11:49
  • Hallo Peter Ich danke Dir das du dich mit dem Problem beschäftigst.

    Ich brauche alle kunden die im Suchfeld "KLMD" haben, aber im gleichen Zeitraum keinen Eintrag "TREF" haben.

    Ich denke man müsste ihm sagen das er nicht jede einzelne Zeile betrachten soll, sondern alle Zeilen des kunden in dem Zeitraum als eins. Aber wie ich das mache hab ich im moment keine Idee.

    Wenn mir da jemand des rätsels lösung gibt wäre ich sehr erleichtert

    Gruß Thomas 

    Dienstag, 28. Juni 2011 11:58
  • Hi tommytom73,
    wenn Du Zustände ausschließen willst, dann ist ein WHERE Kdnr NOT IN .... geeignet. Du ermittelst alle Kdnr, die TREF* haben und schließt die Datensätze mit den ermittelten Kdnr aus, auch, wenn sie KLMD* haben.
     
    --
    Viele Grüße
    Peter
    Dienstag, 28. Juni 2011 12:06
  • Hallo Peter

    bekommt man das über Datatable.Select(...) hin oder sollte ich mich davon verabschieden? 

    Die Aufgabenstellung ist jetzt mal an diesem Beispiel festgemacht. Normalerweise baue ich die Abfrage dynamisch auf dort können ja noch andere Möglichkeiten zutreffen

    Bsp. DataTable.Select(Datum>='01.01.2011' AND Datum<='20.01.2011' AND Suchfeld Like 'KLMD*' AND Suchfeld Like 'TREF*') '// Sollte problemlos gehen
    Bsp. DataTable.Select(Datum>='01.01.2011' AND Datum<='20.01.2011' AND Suchfeld Like 'KLMD*' OR Suchfeld Like 'TREF*')  '// Sollte eigentlich auch gehen
    Bsp. DataTable.Select(Datum>='01.01.2011' AND Datum<='20.01.2011' AND Suchfeld Like 'KLMD*' AND Suchfeld Like 'TREF*' OR Suchfeld Like 'MDFR*)

     

    Würde ich mit LINQ besser hinkommen ?

    Gruß Thomas

    Dienstag, 28. Juni 2011 12:22
  • Hallo Thomas,

    wegen Linq habe ich mal bei Holger Schwichtenberg und Rod Stephens nachgesehen:

    Wenn das Datum bei dir vom Typ String ist wird die Abfrage nicht zuverlässig funktionieren.
    ("20.01.2011" wäre ja grösser als "10.02.2011". Hab deshalb im Beispiel den Datentyp Date verwendet.)

     

     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim dt As DataTable

        dt = New DataTable

        dt.Columns.Add("RecoNo", GetType(Integer))
        dt.Columns.Add("Kdnr", GetType(Integer))
        dt.Columns.Add("Datum", GetType(Date))
        dt.Columns.Add("Suchfeld", GetType(String))

        dt.Rows.Add(1, 3, #1/1/2011#, "KLMD")
        dt.Rows.Add(3, 5, #1/2/2011#, "KLMD")
        dt.Rows.Add(7, 3, #1/10/2011#, "MDFR")
        dt.Rows.Add(10, 7, #1/10/2011#, "TREF")
        dt.Rows.Add(11, 9, #1/10/2011#, "KLMD")
        dt.Rows.Add(17, 3, #1/20/2011#, "TREF")


        Dim a As IEnumerable

        ' Heraus kommen Kundennummer 5 und 9.
       a = (From b In dt.AsEnumerable
             Where b.Field(Of String)("Suchfeld") Like "KLMD*" _
                   And b.Field(Of Date)("Datum") >= #1/1/2011# _
                   And b.Field(Of Date)("Datum") <= #1/20/2011#
             Select b.Field(Of Integer)("Kdnr")).Except _
             (From b In dt.AsEnumerable
              Where b.Field(Of String)("Suchfeld") Like "TREF*" _
                    Select b.Field(Of Integer)("Kdnr"))


      End Sub




    Dienstag, 28. Juni 2011 13:08
  • Danke Markus

    Das Feld Datum ist bei mir natürlich vom Type "Date".

    Ich werde mir das Beispiel mal genau ansehen und schauen in wie weit man das dynamisch generieren könnte. Es ist auf alle fälle schon mal ein lichtblick :-)

     

    Gruß Thomas

    Dienstag, 28. Juni 2011 13:18
  • Geht das dynamisches Linq?

    Ansonsten bleibt meiner Meinung nach der Ansatz von Peter über das SQL zum Füllen der DataTable.

    Etwa:

    "Select * from Kunden
     where Suchfeld Like 'KLMD%'
      and Datum >= '01/01/2011'
      and Datum <= '01/20/2011'
      and Kdnr not in
            (Select Kdnr from Kunden where Suchfeld Like 'Tref%')"
      

    Dienstag, 28. Juni 2011 15:01
  • Danke Markus

    Dynamisches Linq wird nicht funktionieren, das hab ich gestern Abend mal durch gespielt. Aber Dein zweiter Hinweis mit der Select Anweisung sieht genau nach dem aus was ich suche. Ich werde es heute mal probieren.

     

    Danke an euch 2 für die schnellen Ideen.

    Gruß Thomas

    Mittwoch, 29. Juni 2011 06:39
  • tommytom73 schrieb:
    > Hallo Leute ich stehe total auf dem schlauch, und zweifele gerade an
    > meine Denklogik.
    >
    > Ich habe eine DataTable mit folgenden Einträgen
    >
    > RecNo | Kdnr | Datum | Suchfeld
    > 1 3 01.01.2011 KLMD
    > 3 5 02.01.2011 KLMD
    > 7 3 10.01.2011 MDFR
    > 10 7 10.01.2011 TREF
    > 11 9 10.01.2011 KLMD
    > 17 3 20.01.2011 TREF
    >
    > Nun versuche ich über die DataTable.Select(Datum>='01.01.2011' AND
    > Datum<='20.01.2011' AND Suchfeld Like 'KLMD*' AND NOT Suchfeld Like
    > 'TREF*') die Abfrage zu starten
    >
    > Ich bekomme immer Kunde 3 Angezeigt der zwar die erste Bedingung erfüllt
    > "KLMD" ist vorhanden, aber die zweite Bedingung nicht erfüllt "TREF"
    > soll er nicht haben.
    >
     
    Hallo Thomas,
     
    ich sehe da drei Probleme:
    1) Datumsangaben übergibst Du generell besser als typisierten Parameter
    2) Hier unter SQL 2008 R2 ergibt "Suchfeld Like 'KLMD*'" keine
    Übereinstimmung, wenn der Name "KLMD" ist, weil ja nach einer längeren
    Zeichenfolge gefraggt wurde
    3) "AND NOT Suchfeld Like 'TREF*')" trifft zu, wenn der Name "TREF" ist
    (denn "TREF" ist ungleich "TREF" + irgendwelche Zeichen.
     
    Also, versuche einmal:
    Select(Datum>='01.01.2011' AND Datum<='20.01.2011' AND Suchfeld='KLMD'
    AND Suchfeld <> 'TREF')
     
    Gruß
    Johannes Busch
     
     
    Freitag, 1. Juli 2011 08:27
  • Hallo Johannes

    Ist alles richtig was du sagst, wenn ich einen SQL-Server hätte!

    Aber meine Frage bezog sich auf die DataTable die man auch kommplett offline betreiben kann. Mein Problem ist, da ich noch immer mit DBase Datenbanken arbeiten muss, und ich nicht die Datenzugriffstreiber nutzen kann, wegen dem gleichzeitigem Zugriff ("Codebase 6.5") fülle ich das Dataset über die native Codebase DLL mit den Daten die ich brauche. Und dann muss ich halt mit dynamischen Abfragen die Daten in dem Offline DataSet Filtern. Und dabei bleibt mir nur die "DataTable.Select("")" Funktion die mir aber dahingehen Kopfzerbrechen macht weil sie hat nicht so einleuchtend gestrickt ist wie eine SQL-Select Anweisung an einen SQL-Server, wenn man komplexe Abfrage macht.

    Für mich stellt sich im Moment die Frage ob ich mir noch eine SQL-Server Express Datenbank ans Bein binde um die Daten die ich mit der Codebase.dll bekomme in die Express DB rüberlade um dann mit SP's oder Select Anweisungen die Daten Filtere. Im Moment bin ich ein wenig ratlos.

     

    Gruß THomas

    Montag, 4. Juli 2011 05:41
  • Wenn Du mit typisiertem DataSet arbeitest, kannst Du auch anstelle der Select-Methode LinQ nutzen. Da hast Du eine Vielzahl weiterer Möglichkeiten, vor allem auch einfacher. Den Umweg über eine zusätzliche Datenbank würde ich nicht gehen, wenn es dazu keine langfristige Notwendigkeit (z.B. Ablösung von dBase) gibt.
     
    --
    Viele Grüße
    Peter
    Montag, 4. Juli 2011 07:46
  • Ist denn wirklich ein dynamischer Select, also in einem String notwendig? D.h. das dieser Selectstring immer
    erst vom Programm zusammengesetzt werden muss?

    Wenn du das Selektieren über mehrere verschiedene Selectmethoden fest codieren kannst dann geht natürlich auch Linq.

    Oder auch eine While Schleife, die vermutlich besser zu verstehen ist.


    Montag, 4. Juli 2011 13:15
  • Hi Markus,
     
    Wenn du das Selektieren über mehrere verschiedene Selectmethoden fest codieren kannst dann geht natürlich auch Linq.
     
    Eine Linq Anweisung muss nicht fest programmiert sein. Bei variablen Anforderungen kann man Expression Tress nutzen und damit dynamisch Abfragen “zusammenbasteln”.
     
    Oder auch eine While Schleife, die vermutlich besser zu verstehen ist.
     
    Das ist nur eine Frage der Linq-Kenntnisse. Ich finde, dass Linq viel übersichtlicher ist, da die Abfrage kompakter nur an einer Stelle definiert wird anstelle einzelner Codezeilen in ggf. langen Code-Schleifen.
     
    --
    Viele Grüße
    Peter
    • Als Antwort markiert tommytom73 Mittwoch, 13. Juli 2011 09:17
    Dienstag, 5. Juli 2011 03:40
  • Danke an alle die sich mit dem Problem beschäftigt haben.

    Ich war jetzt ein paar Tage nicht online deswegen schreibe ich erst jetzt. Ich habe erstmal eine Klasse geschrieben die den Vergleich auf "AND, AND NOT, OR, OR NOT und NOT" zu Fuss erledigt. Ich werde mich jetzt nochmal intensiv mit LINQ auseinander setzten um das jetzige Ergebnis noch mal Datenbank konform zu lösen, mit den DataTable.Select bin ich nicht richtig weiter gekommen.

    Danke an Peter, Markus und Johannes

    Grüße Thomas 

    Mittwoch, 13. Juli 2011 09:22