最近碰到個SQL Server跑SQL的性能問題,同樣是關系型資料庫,是以在原理層面,不同資料庫之間有些内容是可以借鑒的,但是SQL Server一些細節上和操作層面,略有不同,需要熟悉和積累。
為了模拟,要插入一些測試資料,特别地需要一個存儲日期(要求的格式:yyyymmdd)的字元串類型字段。我用的如下操作方式,可能有些繞,如果各位朋友有更好的方案,可以提出來,一起學習下。
1. 建立一張測試表
create table t1(id int identity(1,1) primary key, c1 varchar(10));
複制
2. 插入10000條測試資料
insert into t1 default values
go 10000
複制
兩點要注意,
(1) go文法在DBeaver提示錯誤,可以在SQL Server Management Studio中執行。
(2) "go 10000"不能帶";"。
此時t1中id字段由于設定了idntitiy,會得到從1到10000的值,但是c1字段為空,由于測試需求,需要讓c1字段存儲"yyyymmdd"的日期數值。
3. 生成随機日期的資料中間表
SQL Server生成随機數可以用函數rand(),例如,
select cast(rand()*1000 as int);
複制
如果生成随機的日期,找了一種方式,
declare @bdate date, @edate date
set @bdate = '20210101'
set @edate = '20210601'
select id, random_date = convert(varchar(10), dateadd(day, abs(checksum(newid())))%datediff(day, @bdate, @edate), @bdate), 112)
into t2 from t1;
複制
其中幾個知識點,
(1) @bdate和@edate是生成随機日期的上下限。
(2) dateidff函數用來擷取日期/時間差,入參是三個,(datepart, startdate, enddate),其中datepart表示傳回兩個指定日期(startdate和enddate)之間所跨的日期或時間邊界的數目,此處用的day,是按照天,還可以改成second按照秒計算等。
(3) checksum()函數傳回按照表的某一行或一組表達式計算出來的校驗和值,他可以将文本改為一串數字。
(4) newid()傳回一個新的GUID号碼,永遠不會重複,而且毫無規律。
(5) dateadd函數顧名思義,将一個時間間隔和指定date的指定datepart相加,傳回一個新的datetime值,入參是三個,(datepart, number, date)。
(6) convert函數,這個有點意思,傳回各種格式的日期字元串,如下所示,我們要的是"yyyymmdd",是以值是112,
Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 1): 05/16/06
Select CONVERT(varchar(100), GETDATE(), 2): 06.05.16
Select CONVERT(varchar(100), GETDATE(), 3): 16/05/06
Select CONVERT(varchar(100), GETDATE(), 4): 16.05.06
Select CONVERT(varchar(100), GETDATE(), 5): 16-05-06
Select CONVERT(varchar(100), GETDATE(), 6): 16 05 06
Select CONVERT(varchar(100), GETDATE(), 7): 05 16, 06
Select CONVERT(varchar(100), GETDATE(),: 10:57:46
Select CONVERT(varchar(100), GETDATE(), 9): 05 16 2006 10:57:46:827AM
Select CONVERT(varchar(100), GETDATE(), 10): 05-16-06
Select CONVERT(varchar(100), GETDATE(), 11): 06/05/16
Select CONVERT(varchar(100), GETDATE(), 12): 060516
Select CONVERT(varchar(100), GETDATE(), 13): 16 05 2006 10:57:46:937
Select CONVERT(varchar(100), GETDATE(), 14): 10:57:46:967
Select CONVERT(varchar(100), GETDATE(), 20): 2006-05-16 10:57:47
Select CONVERT(varchar(100), GETDATE(), 21): 2006-05-16 10:57:47.157
Select CONVERT(varchar(100), GETDATE(), 22): 05/16/06 10:57:47 AM
Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16
Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47
Select CONVERT(varchar(100), GETDATE(), 25): 2006-05-16 10:57:47.250
Select CONVERT(varchar(100), GETDATE(), 100): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 101): 05/16/2006
Select CONVERT(varchar(100), GETDATE(), 102): 2006.05.16
Select CONVERT(varchar(100), GETDATE(), 103): 16/05/2006
Select CONVERT(varchar(100), GETDATE(), 104): 16.05.2006
Select CONVERT(varchar(100), GETDATE(), 105): 16-05-2006
Select CONVERT(varchar(100), GETDATE(), 106): 16 05 2006
Select CONVERT(varchar(100), GETDATE(), 107): 05 16, 2006
Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49
Select CONVERT(varchar(100), GETDATE(), 109): 05 16 2006 10:57:49:437AM
Select CONVERT(varchar(100), GETDATE(), 110): 05-16-2006
Select CONVERT(varchar(100), GETDATE(), 111): 2006/05/16
Select CONVERT(varchar(100), GETDATE(), 112): 20060516
Select CONVERT(varchar(100), GETDATE(), 113): 16 05 2006 10:57:49:513
Select CONVERT(varchar(100), GETDATE(), 114): 10:57:49:547
Select CONVERT(varchar(100), GETDATE(), 120): 2006-05-16 10:57:49
Select CONVERT(varchar(100), GETDATE(), 121): 2006-05-16 10:57:49.700
Select CONVERT(varchar(100), GETDATE(), 126): 2006-05-16T10:57:49.827:
Select CONVERT(varchar(100), GETDATE(), 131): 18/04/1427 10:57:49:920AM
複制
通過以上函數,就可生成一個随機的日期字元串,"select ... into t2 from t1"則從t1表取出所有的記錄(10000條),包括了自增的主鍵字段id,以及每行随機生成的日期字元串c1,插入到t2,字段名稱是id和random_date。
4. 關聯更新t1
其實到第三步,t2表的記錄已經包含了數值字段id以及随機日期字元串字段c1,滿足測試要求了,如果非得用t1,可以再更新下,關聯t2,更新t1,
update t1 set t1 = t2.random_date
from t1, t2
where t1.id = t2.id;
複制
其實很多函數,從名稱上,在各種開發語言和資料庫中都見過,是以很多技術上的知識都是相通的,做到舉一反三、融會貫通,才可以慢慢提高自己的水準。