none
Mit "SELECT Top" und Common.DbDataReader immer den letzten Datensatz auslesen. RRS feed

  • Frage

  • Hallo!

    Counter1 += 1
                cmd1.Parameters.Clear()
                cmd1.CommandText = "SELECT Top " & Counter1 & " * FROM Test100 ORDER BY Daten DESC"
                Dim dr02 As Common.DbDataReader = cmd1.ExecuteReader()
                If (dr02.Read()) Then
                    ID = dr02("ID")
                End If
                dr02.Close()
                dr02.Dispose()

    Ich möchte immer den letzten Datensatz.

    Mit "SELECT Top 3" Datensatz 3, mit "SELECT Top 4" Datensatz 4 usw.

    Manchmal geht das und manchmal bekomme ich immer nur den ersten Datensatz.

    Danke.

    Gruß, Klaus

    Mittwoch, 29. April 2015 17:20

Antworten

  • Hallo Klaus,

    If (dr02.Read()) Then
        ID = dr02("ID")
    End If

    sollte immer den letzten Datensatz auslesen.

    nö, sollte es nicht. Damit liest Du den ersten Datensatz aus, der im DataReader vorhanden ist, sonst nichts. Wenn Du den letzten Datensatz im DataReader willst, musst Du schon eine Schleife verwenden, wenn es mehrere Datensätze geben kann.

    Do While dr02.Read()
        ID = dr02("ID")
    Loop
    

    Sinn macht das IMHO aber nicht wirklich (kenne allerdings deine Anforderungen auch nicht).

    Nach dem, was ich bislang aus deinen Angaben herauslesen konnte, wäre die Variante mit OFFSET und FETCH NEXT bzw. für SQL Server Versionen kleiner als 2012 dann Olafs Variante die bessere Wahl.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    • Als Antwort markiert BlauesBlatt Donnerstag, 30. April 2015 14:16
    Mittwoch, 29. April 2015 20:53
    Moderator

Alle Antworten

  • Mit "SELECT Top 3" Datensatz 3, mit "SELECT Top 4" Datensatz 4 usw.

    Hallo Klaus,

    ich glaube hier liegt ein Missverständnis vor: Mit der TOP Klausel schränkt man die Anzahl der zurückgelieferten Datensätze ein und gibt keine Position an. Will heissen, das TOP 3 Dir 3 Datensätze liefert, aber nicht den dritten Datensatz; siehe MSDN TOP (Transact-SQL)

    Lösen kannst Du es über die Fenster Funktion ROW_NUMBER()

    ;WITH cte AS
        (SELECT *
               ,ROW_NUMBER() OVER (ORDER BY Daten DESC) AS RowNum
         FROM <Tabelle> 
         WHERE <Spalte> LIKE '%ü%'
        )
    SELECT *
    FROM cte
    WHERE RowNum = <deinCounter>


    Olaf Helper

    [ Blog] [ Xing] [ MVP]



    Mittwoch, 29. April 2015 17:35
  • Hallo Olaf,

    das ist richtig.

    "Mit der TOP Klausel schränkt man die Anzahl der zurückgelieferten Datensätze ein"

    Aber:

    Dim dr02 As Common.DbDataReader = cmd1.ExecuteReader()
                If (dr02.Read()) Then
                    ID = dr02("ID")
                End If
                dr02.Close()
                dr02.Dispose()

    sollte immer den letzten Datensatz auslesen.

    So hatte ich das auch nachgelesen.

    Jetzt möchte ich gerne wissen warum es nicht immer funktioniert.

    Danke.

    Gruß, Klaus

    Mittwoch, 29. April 2015 19:13
  • Hi,

    wenn Du SQL Server 2012 oder höher einsetzt, kannst Du auch folgendes verwenden:

    SELECT   *
    FROM     <Tabelle>
    ORDER BY <Spalte>
             OFFSET 10 ROWS
             FETCH NEXT 1 ROWS ONLY

    Siehe dazu bspw.:

      http://dbadiaries.com/new-t-sql-features-in-sql-server-2012-offset-and-fetch


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Mittwoch, 29. April 2015 20:47
    Moderator
  • Hallo Klaus,

    If (dr02.Read()) Then
        ID = dr02("ID")
    End If

    sollte immer den letzten Datensatz auslesen.

    nö, sollte es nicht. Damit liest Du den ersten Datensatz aus, der im DataReader vorhanden ist, sonst nichts. Wenn Du den letzten Datensatz im DataReader willst, musst Du schon eine Schleife verwenden, wenn es mehrere Datensätze geben kann.

    Do While dr02.Read()
        ID = dr02("ID")
    Loop
    

    Sinn macht das IMHO aber nicht wirklich (kenne allerdings deine Anforderungen auch nicht).

    Nach dem, was ich bislang aus deinen Angaben herauslesen konnte, wäre die Variante mit OFFSET und FETCH NEXT bzw. für SQL Server Versionen kleiner als 2012 dann Olafs Variante die bessere Wahl.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    • Als Antwort markiert BlauesBlatt Donnerstag, 30. April 2015 14:16
    Mittwoch, 29. April 2015 20:53
    Moderator
  • sollte immer den letzten Datensatz auslesen. So hatte ich das auch nachgelesen.

    Hallo Klaus,

    wo hast Du das gelesen? In der MDSN (was immer der erste Anlauf sein sollte) steht es jedenfalls nicht: DbDataReader.Read-Methode "...  Standardposition eines Datenreaders ist vor dem ersten Datensatz ..."


    Olaf Helper

    [ Blog] [ Xing] [ MVP]


    Donnerstag, 30. April 2015 06:35
  • Kann es sein, dass Du logisch den dritten Datensatz meinst, da Du ja das ORDER BY mit DESC verwendet hast?
    Ihr also etwas aneinander vorbei redet?

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Donnerstag, 30. April 2015 08:25
  • Hallo Christoph,

    ich meine immer den letzten Datensatz von Top 1, Top 2 ... Top 10 usw.

    Da ich ja nach der Sortierung nicht weiß, welche ID der Datensatz hat.

    Danke.

    Gruß, Klaus

    Donnerstag, 30. April 2015 13:59
  • Hallo Olaf,

    ich habe das im Internet gelesen.

    Weiß aber nicht mehr auf welcher Seite.

    Danke.

    Gruß, Klaus

    Donnerstag, 30. April 2015 14:07
  • Hallo Stefan,

    mit:

    Do While dr02.Read()
        ID = dr02("ID")
    Loop

    geht was ich möchte.

    Vielen Dank!

    Gruß, Klaus

    Donnerstag, 30. April 2015 14:16