SqlServer本身並沒有提供隨機讀取記錄的功能,但我們可以通過一些方法來實現這個目的。本文介紹了其中幾種方法並比較了各自的優劣。
方法一:
直接通過Sql語句實現,如:
select top n *
from tableA
order by newid()
這是最簡單的方法,通過調用SqlServer的newid()函數(產生GUID—全局唯一標志符)來產生隨機記錄。
采用這種方法時,需要將表中所有記錄與newid()生成的值進行比較從而進行排序。因此,如果表中的記錄較多,操作會非常緩慢。
方法二:
假設表中有一個自增長主鍵,增量為1。這時我們可以這樣處理,取出主鍵的邊界值(最大值和最小值),然後通過一個算法得到介於(包括)兩個邊界之間的隨機值,最後按照這個值取出對應記錄。下面是C#的例子:
//生成隨機數
Random rand = new Random();
int num = rand.Next(MinVal,MaxVal + 1); //MinVal為主鍵的最小值,MaxVal為主鍵的最大值
//讀取記錄的Sql字符串
string SqlStr = "select * from tableA where PK = " + num;
這種方法較前一種方法的操作速度有了較大提高(特別是在大數據量的情況下)。但只有當主鍵值是連續的,中間沒有斷開的情況,並且增量為1時才能用這種方法。那麼,如何才能解決這個問題呢?請繼續往下看。
方法三: 對方法二進行了改進。主要思路是,將表中所有的主鍵值讀進一個數組,從數組中隨機讀出一個值,按照這個值取出對應記錄。下面是C#的例子:
//將主鍵值讀進ArrayList
ArrayList DataIndex = new ArrayList();
while (sdr.Read()) //sdr為存放所有主鍵值的SqlDataReader
{
DataIndex.Add(sdr[0]); //存入ArrayList
}
//從ArrayList中隨機讀取數據項
Random rand = new Random();
int num = Convert.ToInt32(DataIndex[rand.Next(DataIndex.Length)]);
//讀取記錄的Sql字符串
string SqlStr = "select * from tableA where PK = " + num;
這樣不管主鍵是否為自增長字段,也不管數值是否連續,都能夠應付自如了。經過筆者的測試,在數據量為50萬的情況下代碼運行速度幾乎沒有受到什麼影響,可見ArrayList的操作性能是可以信賴的。