我有一个查询从Access数据库返回随机不同的行。这是查询:
SELECT * FROM
(SELECT DISTINCT m.MemberID, m.Title, m.FullName, m.Address,
m.Phone, m.EmailAddress, m.WebsiteAddress FROM Members AS m INNER JOIN MembersForType AS t ON m.MemberID = t.MemberID WHERE
(Category = 'MemberType1' OR Category = 'MemberType2')) as Members
ORDER BY RND(members.MemberID) DESC
当我在Access中运行它时,它会按照随机排序顺序每次以不同的顺序返回行。当我通过我的网络应用程序运行它时,行每次都以相同的顺序返回。以下是我在代码隐藏中调用它的方法:
private void BindData()
{
using (AccessDataSource ds = new AccessDataSource("~/App_Data/mydb.mdb", GetSQLStatement()))
{
ds.DataSourceMode = SqlDataSourceMode.DataReader;
ds.CacheDuration = 0;
ds.CacheExpirationPolicy = DataSourceCacheExpiry.Absolute;
ds.EnableCaching = false;
listing.DataSource = ds.Select(new DataSourceSelectArguments());
listing.DataBind();
if (listing.Items.Count == 0)
noResults.Visible = true;
else
noResults.Visible = false;
}
}
我添加了有关缓存的所有内容,因为我认为可能正在缓存查询但结果是相同的。我在代码中放了一个断点,以确保查询与上面相同,并且它是。
有什么想法吗?这让我疯了。
答案 0 :(得分:2)
对新连接执行ACE / Jet RND功能时,每次都使用相同的种子值。使用MS Access时,每次都使用相同的连接,这解释了为什么每次都获得不同的值。
考虑这些VBA示例:第一个在每次迭代时使用新连接:
Sub TestDiff()
Dim con As Object
Set con = CreateObject("ADODB.Connection")
With con
.ConnectionString = _
"Provider=MSDataShape;Data " & _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Tempo\Test_Access2007.accdb"
.CursorLocation = 3
Dim i As Long
For i = 0 To 2
.Open
Debug.Print .Execute("SELECT RND FROM OneRowTable;")(0)
.Close
Next
End With
End Sub
输出:
0.705547511577606
0.705547511577606
0.705547511577606
每次都注意相同的值。
第二个示例在每次迭代时使用相同的连接(.Open和.Close语句在循环外重定位):
Sub TestSame()
Dim con As Object
Set con = CreateObject("ADODB.Connection")
With con
.ConnectionString = _
"Provider=MSDataShape;Data " & _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Tempo\Test_Access2007.accdb"
.CursorLocation = 3
.Open
Dim i As Long
For i = 0 To 2
Debug.Print .Execute("SELECT RND FROM OneRowTable;")(0)
Next
.Close
End With
End Sub
输出:
0.705547511577606
0.533424019813538
0.579518616199493
每次注意不同的值。
在VBA代码中,您可以使用Randomize关键字为Rnd()函数设定种子,但我不认为这可以在ACE / Jet中完成。一种解决方法是使用ACE / Jet的最低有效小数部分NOW()niladic函数,例如:类似的东西:
SELECT CDBL(NOW()) - ROUND(CDBL(NOW()), 4) FROM OneRowTable
答案 1 :(得分:0)
我会将RND移动到内部SELECT
SELECT * FROM
(SELECT DISTINCT m.MemberID, RND(m.MemberID) as SortOrder, m.Title,
m.FullName, m.Address, m.Phone, m.EmailAddress, m.WebsiteAddress
FROM Members AS m
INNER JOIN MembersForType AS t ON m.MemberID = t.MemberID
WHERE
(Category = 'MemberType1' OR Category = 'MemberType2')) as Members
ORDER BY
Members.SortOrder DESC
答案 2 :(得分:0)
您可以将时间用作RND字段的一个参数
现在变暗为DateTime = DateTime.Now
Dim millSec As Integer = Now.Millisecond
finalQuery =“SELECT * FROM wordInfo ORDER BY Rnd( - (1000 * ROUND(”+ millSec.ToString(“N”)+“,0))* [ID])”
所以这里从日期和时间值开始,取毫秒值,它将是整数,并通过舍入它在sql查询中使用。
wordInfo是表名 ID是数据库表中的列名
每次都给出随机顺序(因为毫秒值不同)是相同的连接或新连接。