需求:用SQL腳本更新數據庫某個字段為六位隨機值
環境:SQL Server 2008,數據庫內有上千條數據
問題1:六位隨機值
步驟1:隨機數的SQL函數為rand() ,而rand()生成的是0-1之間的小數。
步驟2:將rand()*1000000則看似可以得到有六位數了(小數部分暫時忽略不算)。可是,假設rand()得到的是一個類似0.0xxx的小數,rand()*1000000就會只有五位整數部分,或許更少。
步驟3:rand()*(999999-100000)+100000這樣就可以保證這個隨機數的整數部分一定有六位,當然隨機數的第一位永遠不可能為0,這只能說取舍吧,只能為1-9也不是什么大問題。總而言之,隨機數的整數部分解決了。然后需要將隨機數的小數部分去掉。
步驟4:cast(rand()*(999999-100000)+100000 as nvarchar(6)) cast的作用是類型轉換,將隨機數轉化為nvarchar(6),得到的結果就是我們需要的隨機數了。
問題2:更新每一條數據的某一字段
想法1:
UPDATE [test].[dbo].[my_table] SET [test_rand] = cast(rand()*(999999-100000)+100000 as nvarchar(6))
這種想法是有多天真啊。這樣更新下來只能導致這個字段變成相同的一個隨機值。
想法2:寫一段程序,每次調用想法1,直到所有數據發生變化,這個也是相當的天真。首先,需求本身要求的就是SQL腳本來實現,所有即使是寫好了程序也是無用功,而且這樣的做法本身就很垃圾。每次要連接一次數據庫,如果上萬條就要連接上萬次。不可取。
想法3:想來想去,首先一定要有循環才能實現。但是循環標志是什么呢。經過向前輩的虛心求教(心虛~~),提示由游標這個東西可以實現。因為本身對SQL接觸甚少,原諒我不知道有這個東西。
步驟1:聲明游標
DECLARE user_extension_cursor CURSOR FOR SELECT id FROM [mtrade].[dbo].[user]
聲明游標的時候指定游標指的是數據庫的哪一個字段。(在這里只能選擇作為主鍵的id)
步驟2:需要用FETCH來獲取游標
FETCH NEXT FROM user_extension_cursor INTO @user_id
步驟3:循環更新字段的值
WHILE @@FETCH_STATUS = 0 BEGIN UPDATE [mtrade].[dbo].[user] SET [user].[extension] = cast(rand()*(999999-100000)+100000 as nvarchar(6)) WHERE id = @user_id FETCH NEXT FROM user_extension_cursor INTO @user_id END
這樣才算大功告成。
以下是完整的SQL游標更新隨機數的SQL代碼(具體細節沒有過多的說明,主要鄙人對於SQL不是很熟)
-- 更新 my_table 的 test_rand 字段 DECLARE @user_id varchar(36) DECLARE user_extension_cursor CURSOR FOR SELECT id FROM [test].[dbo].[my_table] OPEN user_extension_cursor; FETCH NEXT FROM user_extension_cursor INTO @user_id WHILE @@FETCH_STATUS = 0 BEGIN UPDATE [test].[dbo].[my_table] SET [my_table].test_rand = cast(rand()*(999999-100000)+100000 as nvarchar(6)) WHERE id = @user_id FETCH NEXT FROM user_extension_cursor INTO @user_id END CLOSE user_extension_cursor; DEALLOCATE user_extension_cursor; ---
學藝不精,以此共勉。