none
Zufällige Datensätze aus Jet-Tabelle RRS feed

  • Frage

  • Hallo!

    Ich möchte n beliebige Datensätze aus einer Jet-Tabelle abrufen:

    Module Module1
        Sub Main()
    
            Dim dt As New DataTable
    
            Using conn As New OleDbConnection( _
                "Provider=Microsoft.Jet.Oledb.4.0;" & _
                "Data Source=MyDatabase")
    
                conn.Open()
    
                Using cmd As New OleDbCommand( _
                    "SELECT TOP 10 Id, Col1, Col2, Col3 " & _
                    "FROM MyTable " & _
                    "ORDER BY RND(Id)", _
                    conn)
    
                    Using da As New OleDbDataAdapter(cmd)
                        da.Fill(dt)
                    End Using
    
                End Using
    
                conn.Close()
    
            End Using
    
            For Each r As DataRow In dt.Rows
                Console.WriteLine(r("Id").ToString)
            Next
    
            Console.ReadLine()
        End Sub
    
    End Module
    

    Die Datensätze werden beim *ersten* Zugriff auch durchaus in zufälliger Abfolge ausgegeben. Rufe ich jedoch die Prozedur wiederholt auf, so bleibt die Reihenfolge stets die gleiche. Der Weg über ein Subselect oder eine gespeicherte Prozedur führt auch nicht weiter.

    Rufe ich dagegen das identische Statement als kompilierte Abfrage in Access selbst auf, erhalte ich das gewünschte Ergebnis, die Datensätze in jeweils neuer, geänderter Reihenfolge.

    Was übersehe ich hier? Wie müsste man vorgehen?

    Anschlussfrage: Ist das Ergebnis meiner Recherchen zutreffend, demzufolge die Anzahl n der Datensätze nicht zu parametrisieren ist?

    Danke für Anworten

    Jo

    Mittwoch, 15. Januar 2014 13:38

Antworten

  • Hallo Jo,

    heute habe ich Access vor mir... Das Problem ist anscheinend dass der Zahlengenerator für jede neu eröffnete Verbindung zurückgesetzt wird. Und so das Gleiche dabei heraus kommt. Lässt man die Verbindung offen, gibt es neue Zahlen:

            Using connection As New OleDbConnection("Provider=Microsoft.Jet.Oledb.4.0;Data Source=C:\TEMP\A00.mdb;")
                connection.Open()
    
                For index = 0 To 5
                    Dim table As New DataTable("Random")
    
                    Using adapter As New OleDbDataAdapter(
                        "SELECT TOP 10 Id " &
                        "FROM Tabelle1 " &
                        "ORDER BY Rnd(id * Time())",
                        connection)
    
                        adapter.Fill(table)
                    End Using
                    For Each row As DataRow In table.Rows
                        Console.WriteLine("{0} => {1}", index, row("Id"))
                    Next
                    Console.WriteLine()
                Next
            End Using
    

    Setzt man die For Schleife nach außen - um das Using connection herum - so bekommt man fünfmal gleiche Ergebnisse. Welche Formel man nimmt beeindruckt die Verbindung anscheinend nicht.

    Gruß Elmar

    • Als Antwort markiert Jo Neumann Donnerstag, 16. Januar 2014 11:24
    Donnerstag, 16. Januar 2014 10:32
    Beantworter

Alle Antworten

  • Hallo Jo,

    ungetestet, probiere mal:

    SELECT TOP 10 Id, Col1, Col2, Col3 
    FROM MyTable 
    ORDER BY RND(Id * Now());

    d. h. multipliziere den Wert mit einem Variablen Wert wie Now() - denn Access / VBA RND liefert ansonsten gleiche Werte.

    Zur Anschlussfrage: Access bietet keine Möglichkeit den Wert für TOP variabel zu gestalten (im Gegensatz zum SQL Server ab 2005) - da müsstest Du das SQL anpassen.

    Gruß Elmar

    Mittwoch, 15. Januar 2014 14:21
    Beantworter
  • Hallo Elmar,

    danke für Deine Anwort

    ungetestet, probiere mal:

    SELECT TOP 10 Id, Col1, Col2, Col3 
    FROM MyTable 
    ORDER BY RND(Id * Now());

    das hat leider nicht funktioniert. Die Reihenfolge der Werte bleibt hartnäckig die gleiche. Siehst Du einen akzeptablen Workaround? Eine Spalte an die Tabelle anhängen und vorm Aufruf mit Net-Zufallswerten füllen?

    Nebenbei: Ich habe mal auf Deine Anregung Daten und Code auf den SQL Server übertragen. Da käme ich sowohl mit einem variablem Wert für TOP als auch mit zufälligen Datensätzen (NEWID) deutlich einfacher zum Ziel.

    Danke und Gruß

    Jo

    Mittwoch, 15. Januar 2014 21:08
  • Hallo Jo,

    der Parameter muss vom Typ Int sein.

    Mit folgendem Parameter sollte es funktionieren:

    Order BY (Second(Now())*Id)

    Dabei gibt es aber nur jede Sekunde eine neue Reihenfolge, wenn das nicht reicht müsste man eine andere Funktion für den Startwert finden.

    Grüße

    Roland

    • Bearbeitet dt125fahrer Donnerstag, 16. Januar 2014 07:11 Ergänzung entfernt
    Donnerstag, 16. Januar 2014 06:46
  • ...muss mich korrigieren. Habe den Code mal selbst in VisualStudio getestet.

    Über OLEDB scheint das wirklich nicht zu funktionieren :-(

    Mit SQLServer gibt es die Möglichkeit über NEWID()

    also:

    SELECT TOP 10 Id, Col1, Col2, Col3 
    FROM MyTable 
    ORDER BY NEWID()

    Das hat funktioniert, wird Dir aber wahrscheinlich an der Stelle nicht weiterhelfen.

    Donnerstag, 16. Januar 2014 08:39
  • ...muss mich korrigieren. Habe den Code mal selbst in VisualStudio getestet.

    Über OLEDB scheint das wirklich nicht zu funktionieren :-(

    Mit SQLServer gibt es die Möglichkeit über NEWID()

    also:

    SELECT TOP 10 Id, Col1, Col2, Col3 
    FROM MyTable 
    ORDER BY NEWID()

    Das hat funktioniert, wird Dir aber wahrscheinlich an der Stelle nicht weiterhelfen.

    Donnerstag, 16. Januar 2014 08:39
  • Hallo Jo,

    heute habe ich Access vor mir... Das Problem ist anscheinend dass der Zahlengenerator für jede neu eröffnete Verbindung zurückgesetzt wird. Und so das Gleiche dabei heraus kommt. Lässt man die Verbindung offen, gibt es neue Zahlen:

            Using connection As New OleDbConnection("Provider=Microsoft.Jet.Oledb.4.0;Data Source=C:\TEMP\A00.mdb;")
                connection.Open()
    
                For index = 0 To 5
                    Dim table As New DataTable("Random")
    
                    Using adapter As New OleDbDataAdapter(
                        "SELECT TOP 10 Id " &
                        "FROM Tabelle1 " &
                        "ORDER BY Rnd(id * Time())",
                        connection)
    
                        adapter.Fill(table)
                    End Using
                    For Each row As DataRow In table.Rows
                        Console.WriteLine("{0} => {1}", index, row("Id"))
                    Next
                    Console.WriteLine()
                Next
            End Using
    

    Setzt man die For Schleife nach außen - um das Using connection herum - so bekommt man fünfmal gleiche Ergebnisse. Welche Formel man nimmt beeindruckt die Verbindung anscheinend nicht.

    Gruß Elmar

    • Als Antwort markiert Jo Neumann Donnerstag, 16. Januar 2014 11:24
    Donnerstag, 16. Januar 2014 10:32
    Beantworter
  • Hallo Elmar,

    Lässt man die Verbindung offen, gibt es neue Zahlen:

    [...]

    Jetzt läufts rund!

    Herzlichen Dank dafür!

    Grüße

    Jo

    Donnerstag, 16. Januar 2014 11:28
  • Hallo Roland,

    danke auch an Dich für Interesse und Antort,

    Gruß

    Jo

    Donnerstag, 16. Januar 2014 11:32