SQL Server 2008中新的日期時(shí)間數(shù)據(jù)類型
SQL Server 2008 終于發(fā)布新版了,雖然還只是另一個(gè)社區(qū)測(cè)試版而非完全版。每當(dāng)新軟件發(fā)布,大家最關(guān)系的問(wèn)得最多的問(wèn)題就是:有些什么新特性?SQL Server 2008有很多新功能和新工具。不過(guò),本文還是主要為大家介紹SQL Server 2008的新數(shù)據(jù)類型,并對(duì)DATETIME數(shù)據(jù)類型的功能進(jìn)行專門討論。
SQL Server 2008中DATETIME功能的最大轉(zhuǎn)變就是引入了四種DATETIME數(shù)據(jù)類型,分別為DATE、TIME、DATETIMEOFFSET和DATETIME2;此外還增加了新的DATETIME函數(shù)功能。
下面首先來(lái)討論一下四種新數(shù)據(jù)類型的功能和用法。
DATE?據(jù)類型
在SQL Server 2008中,沒(méi)有專門只用來(lái)存儲(chǔ)日期(不包括時(shí)間)的特定數(shù)據(jù)類型,只能使用DATETIME或SMALLDATETIME數(shù)據(jù)類型來(lái)完成此操作。但是,當(dāng)你輸入日期之后,會(huì)顯示還有一個(gè)時(shí)間的組分需要輸入,其初始顯示為12:00 AM。如果只想在輸出結(jié)果中顯示日期那一部分,就必須修改輸出格式。大部分情況下,可以使用getdate()函數(shù)來(lái)存儲(chǔ)當(dāng)前日期。要在SQL Server 2008中的SMALLDATETIME或DATETIME列中保存getdate()的函數(shù)值,同時(shí)也會(huì)保存了當(dāng)前的時(shí)間,而這可能會(huì)引發(fā)很多問(wèn)題。舉例而言,如果你使用以下的語(yǔ)句,想根據(jù)給定的日期來(lái)搜索記錄:
select * from tblDate where [Date] = '2007-12-01'
由于Date列里含有時(shí)間組分,這個(gè)命令將無(wú)法正常執(zhí)行, 因此,你必須執(zhí)行以下的查詢操作:
select * from tblDate where datediff(d,[Date],‘2007-12-01’) =0
盡管上面的查詢操作可以行得通,不過(guò)Date列中符合要求的索引很可能不會(huì)被使用。不過(guò)你還是可以使用上面的查詢操作調(diào)出少量的記錄。雖然可以利用工作區(qū),但很明顯有必要增加一種去掉時(shí)間值的DATE數(shù)據(jù)類型來(lái)減少潛在的錯(cuò)誤。來(lái)看看以下的語(yǔ)法:
DECLARE@dtasDATE
SET@dt=getdate()
PRINT@dt
以上腳本的輸出結(jié)果只有日期,不包括時(shí)間部分。DATE數(shù)據(jù)類型的取值范圍從0001-01-01到9999-12-31。
TIME數(shù)據(jù)類型
就像日期數(shù)據(jù)類型一樣,如果你只想存儲(chǔ)時(shí)間數(shù)據(jù)而不需要日期部分就可以利用TIME數(shù)據(jù)類型。下面就是利用TIME數(shù)據(jù)類型進(jìn)行查詢的例子:
DECLARE@dtasTIME
SET@dt=getdate()
PRINT@dt
以上腳本輸出結(jié)果只包含時(shí)間部分,其取值范圍從00:00:00.0000000到23:59:59.9999999。
DATETIME2數(shù)據(jù)類型
新的DATETIME2數(shù)據(jù)類型也是一種數(shù)據(jù)時(shí)間混合的數(shù)據(jù)類型,不過(guò)其時(shí)間部分秒數(shù)的小數(shù)部分可以保留不同位數(shù)的值,比原來(lái)的 DATETIME數(shù)據(jù)類型取值范圍要廣。用戶可以根據(jù)自己的需要通過(guò)設(shè)置不同的參數(shù)來(lái),設(shè)定小數(shù)位數(shù),最高可以設(shè)到小數(shù)點(diǎn)后七位(參數(shù)為7),也可以不要小數(shù)部分(參數(shù)為0),以此類推。以下是利用DATETIME2的查詢語(yǔ)句:
DECLARE@dt7datetime2(7)
?SET@dt7=Getdate()
PRINT@dt7
該語(yǔ)句的輸出結(jié)果中時(shí)間的秒數(shù)部分精確到小數(shù)點(diǎn)后第七位。
DATETIMEOFFSET數(shù)據(jù)類型
如果把日期和時(shí)間數(shù)據(jù)保存在一列里,是不會(huì)提示該日期和時(shí)間屬于哪一個(gè)時(shí)區(qū)的。時(shí)區(qū)的提示非常重要,特別是當(dāng)你處理數(shù)據(jù)包含了多個(gè)不同時(shí)區(qū)的國(guó)家時(shí)。新的DATETIMEOFFSET數(shù)據(jù)類型可以定義一個(gè)日期和時(shí)間組合,其中時(shí)間以24小時(shí)制顯示,并帶有時(shí)區(qū)提示。下面的語(yǔ)句說(shuō)明了 DATETIMEOFFSET數(shù)據(jù)類型的用法:
DECLARE@dtDATETIMEOFFSET(0)
SET@dt='2007-12-0421:20:30-1:00'
DECLARE@dt1DATETIMEOFFSET(0)
SET@dt1='2007-12-0421:20:30+5:00'
selectDATEDIFF(hh,@dt,@Dt1)
DateTime函數(shù)
目前我們可以在SQL Server 2008和SQL Server 2000中使用GETDATE函數(shù)來(lái)查詢當(dāng)前的日期和時(shí)間。此外,在SQL Server 2005中,還有另外幾個(gè)類似的日期時(shí)間函數(shù),分別為:CURRENT_TIMESTAMP、DATEADD、DATEDIFF、DATENAME、 DATEPART、GETUTCDATE、DAY、 MONTH和YEAR。而在SQL Server 2008中,除了上述這些函數(shù)外,又新增了五個(gè)函數(shù),分別為SYSDATETIME、SYSDATETIMEOFFSET、 SYSUTCDATETIME、SWITCHOFFSET和TODATETIMEOFFSET。其中SYSDATETIME函數(shù)返回目前系統(tǒng)的時(shí)間戳,不帶時(shí)區(qū)提示,能夠精確到毫秒級(jí)。SYSDATETIMEOFFSET函數(shù)和SYSDATETIME函數(shù)功能類似,不過(guò)包含了時(shí)區(qū)值。 SYSUTCDATETIME返回以世界標(biāo)準(zhǔn)時(shí)間(又稱協(xié)調(diào)世界時(shí),也就是格林威治時(shí)間)表示的日期和時(shí)間,也精確到毫秒級(jí),是根據(jù)當(dāng)前SQL Server運(yùn)行所在地服務(wù)器所設(shè)置的本地時(shí)間和時(shí)區(qū)得來(lái)的。SYSDATETIME和SYSUTCDATETIME兩個(gè)函數(shù)返回的都是 DATETIME2數(shù)據(jù)類型,而SYSDATETIMEOFFSET函數(shù)返回DATETIMEOFFSET數(shù)據(jù)類型。
SWITCHOFFSET函數(shù)
SWITCHOFFSET函數(shù)返回DATETIMEOFFSET數(shù)據(jù)類型的值,不再根據(jù)存儲(chǔ)的時(shí)區(qū)偏移值取值,而是根據(jù)設(shè)定的新時(shí)區(qū)偏倚值來(lái)取值??纯聪旅孢@個(gè)語(yǔ)句:
select SYSDATETIMEOFFSET(), SWITCHOFFSET (SYSDATETIMEOFFSET(), '-14:00')
該腳本返回兩個(gè)列,第一列是根據(jù)世界標(biāo)準(zhǔn)時(shí)間得到的當(dāng)前日期和時(shí)間值,第二列則是根據(jù)給定的時(shí)區(qū)偏移值返回的日期時(shí)間值。
TODATETIMEOFFSET函數(shù)
TODATETIMEOFFSET函數(shù)可以把本地日期或時(shí)間值以及特定的時(shí)區(qū)偏移值轉(zhuǎn)變?yōu)橐粋€(gè)datetimeoffset值。運(yùn)行以下腳本,你會(huì)看到返回的結(jié)果中除了當(dāng)前日期和時(shí)間外,還增加了時(shí)區(qū)值。
select TODATETIMEOFFSET (GETDATE(),'+11:00')
轉(zhuǎn)換函數(shù)
CONVERT函數(shù)可以從DATETIME數(shù)據(jù)類型的組成中抽取時(shí)間值或者日期值。運(yùn)行以下腳本,返回結(jié)果的第一列為當(dāng)前日期,第二列為當(dāng)前時(shí)間。
select CONVERT(date, GETDATE()),CONVERT(time, GETDATE())
使用新DATETIME數(shù)據(jù)類型進(jìn)行轉(zhuǎn)換的注意事項(xiàng)
如果你要增加DATE和TIME列,不能夠像SMALLDATETIME數(shù)據(jù)類型一樣加載,否則會(huì)返回以下的錯(cuò)誤信息:Operand data type date is invalid for add operator。
你可以嘗試把這兩列設(shè)置為浮點(diǎn)型數(shù)據(jù),一起存入,并把結(jié)果轉(zhuǎn)換成SMALLDATETIME或DATETIME列。(記住,當(dāng) SMALLDATETIME數(shù)據(jù)存儲(chǔ)成浮點(diǎn)型時(shí),日期值為整數(shù)部分而時(shí)間值為小數(shù)部分)不過(guò),這也會(huì)返回一個(gè)錯(cuò)誤信息:Explicit conversion from data type date to float is not allowed。
正確的做法是把兩列都轉(zhuǎn)換為SMALLDATETIME數(shù)據(jù),并一起存入。例如使用以下腳本,你就可以得到輸出結(jié)果:
Declare@dtasDATE
Set@dt=getdate()
Declare@dttasTIME
Set@dtt=getdate()
Selectcast(@dtassmalldatetime)+cast(@dttassmalldatetime)