Benutzer mit den meisten Antworten
Zufällige Datensätze aus Jet-Tabelle

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
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
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
- Bearbeitet Elmar BoyeEditor Mittwoch, 15. Januar 2014 14:23 TOP
-
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
-
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
-
...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.
-
...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.
-
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