SQL Server時間格式淺析

來源:互聯網
上載者:User

 資料庫中時間日期往往是一個很重要的資料。各個電腦上的時間往往不同,為了在資料庫中插入統一的時間,如果是取當前時刻,最好直接從資料庫伺服器讀取。比如有一個表名為tablename的表格,其中columnname欄位是目前記錄插入時的目前時間,則該插入語句應寫為:insert into table name (columnname,…) values
(GetDate(),…)。這樣GetDate()函數將資料庫伺服器的目前時間插入該記錄中。

在尋找所有當天的記錄前,先來分析一下T-SQL的時間日期表示方式。在T-SQL中,時間日期格式資料類型實際上是一個浮點數類型,記錄的是目前時間到1900年1月1日0時的天數,加上剩餘的時間化成小數。下面的語句:

select getdate() as 目前時間,cast(getdate() as float) as 距1900年1月1日天數

將返回:

 

目前時間                       
距1900年1月1日天數

---------------------------
-----------------------------------------------------

2001-11-10
11:05:35.733                       
37203.462219135799

 

(1 row(s)
affected)

 

所以要尋找當天插入的記錄,理所應當的會想到用GetDate()擷取兩個目前時間,並將前一個用Convert或Cast函數轉換為整數(記為IntToday),將後一個轉換為浮點數(記為FloatNow),再將需要尋找的記錄日期也轉換為浮點數(記為FloatCheck),只要使用條件”…where FloatCheck between IntToday and FloatNow”就可以找出哪些時間是屬於今天的時間。現在看起來確實如此。

表格testtable有三個欄位,id是一個自動成長的主鍵,inserttime是記錄插入時刻的時間,comment欄位是為了方便觀察設立的。該表格中共有四條記錄,前兩條記錄是11月9日插入的,後兩條是11月10日插入的。

第一條SQL語句返回該表格中的所有記錄。

select * from
testtable

 

id                   
inserttime                              comment

------------
--------------------------------------
--------------------------------------------

1                   2001-11-09
10:28:42.943                    第一條記錄

2                   2001-11-09
17:43:22.503                    第二條記錄

3                   2001-11-10
11:29:11.907                     第三條記錄

4                   2001-11-10
11:29:51.553                    第四條記錄

 

(4 row(s) affected)

 

下面的語嘗試選出今天(2001年11月10日)插入的記錄,該語句執行時的資料庫伺服器時間是2001-11-10 11:40:57.800

 

select * from testtable where cast(inserttime as float) between
cast(GetDate() as int) and cast(GetDate() as float)

 

id                   
inserttime                              comment

------------
--------------------------------------
--------------------------------------------

3                   2001-11-10
11:29:11.907                     第三條記錄

4                   2001-11-10
11:29:51.553                    第四條記錄

(2 row(s) affected)

 

這條語句成功地過濾了前一天產生的記錄。

現在地11點51分,午餐時間到了,我要等一會再繼續工作。

12點26分,開始工作前讓我先欣賞一下自己的“傑作”。可是,出問題了,那條用來過濾的語句什麼也沒有返回。去掉where子句再執行,原來的記錄還在。也就是說資料庫裡的記錄不再滿足條件了。沒有別的辦法,讓我們來看看條件發生了什麼變化。

執行語句:

select cast(inserttime as float) as FloatCheck,cast(GetDate() as int)
as IntToday,cast(GetDate() as float) as FloatNow from testtable

結果返回:

 

FloatCheck                      IntToday                              FloatNow

-----------------------------------------------------------------------------------

3702.43660814043               
                   37204                                 3703.524545756176

3702.728274807101                  
37204                                 3703.524545756176

3703.478610030863                  
37204                  
3703.524545756176

3703.479068904322                  
37204                  
3703.524545756176

 

(4 row(s) affected)

 

注意到IntToday比FloatNow大,這就是條件不再滿足的原因。原來cast()函數並不簡單地去掉小數,而是四捨五入,所以下午(cast(GetDate() as int))返回的值比上午返回的要大1。在程式中不可能先判斷上午和下午再選擇SQL語句執行,因此有必要對GetDate()返回的值做一下數學上的處理。注意到cast(GetDate() as int)當天下午返回的值和前一天下午返回的值一樣大,我的辦法是先將GetDate()值減去0.5。這樣如果是上午,減去0.5後變為前一天的下午,小數部分“入”,如果是下午,減去0.5後變為當天上午,小數部分“去”。寫成的新語句如下:

select * from testtable where cast(inserttime as float) between
cast(GetDate()-0.5 as int) and cast(GetDate() as float)

執行結果正常。

另外,事實上float(也可能是real)資料類型是DateTime資料類型的基本類型,所以它們之間可以透明地比較,也就是說不必進行轉換就能直接比較,像這樣:

select * from testtable where inserttime between cast(GetDate()-0.5
as int) and GetDate()

我先前做的轉換隻是為了方便說明。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.