2014年10月1日 星期三

關於 DB2 時間的處理 (參考文章)

關於 DB2 時間的處理 (參考文章)

本文摘錄於 IBM DevelopWorks 網站,對處理 BD2 時間的問題有很大的幫助:

這篇文章是為那些剛接觸 DB2 並想理解如何操作日期和時間的新手而寫的。
使用過其他資料庫的大部分人都會很驚喜地發現在 DB2 中操作日期和時間是多麼簡單。

要使用 SQL 獲得當前的日期、時間及時間戳記,請參考適當的 DB2 暫存器:

SELECT current date FROM sysibm.sysdummy1
SELECT current time FROM sysibm.sysdummy1
SELECT current timestamp FROM sysibm.sysdummy1

sysibm.sysdummy1 表是一個特殊的記憶體中的表,
用它可以發現如上面演示的 DB2 暫存器的值。
您也可以使用關鍵字 VALUES 來對暫存器或運算式求值。
例如,在 DB2 命令行處理器(Command Line Processor,CLP)上,
以下 SQL 語句揭示了類似資訊:

VALUES current date
VALUES current time
VALUES current timestamp

在之後的例子中,我將只提供函數或運算式,
而不再重複 SELECT ... FROM sysibm.sysdummy1 或使用 VALUES 子句。

要使當前時間或當前時間戳記調整到 GMT/CUT,
則把當前的時間或時間戳記減去當前時區暫存器:

current time - current timezone
current timestamp - current timezone

給定了日期、時間或時間戳記,
則使用適當的函數
可以單獨抽取出(如果適用的話)年、月、日、時、分、秒及微秒各部分:

YEAR(current timestamp)
MONTH(current timestamp)
DAY(current timestamp)
HOUR(current timestamp)
MINUTE(current timestamp)
SECOND(current timestamp)
MICROSECOND(current timestamp)

從時間戳記單獨抽取出日期和時間也非常簡單:

DATE(current timestamp)
TIME(current timestamp)

由於沒有更好的詞彙還作為函數名稱,
所以您還可以使用英語來執行日期和時間計算:

current date + 1 YEAR
current date + 3 YEARS + 2 MONTHS + 15 DAYS
current time + 5 HOURS - 3 MINUTES + 10 SECONDS

要計算兩個日期之間的天數,您可以對日期作減法,如下所示:

days (current date) - days (date('1999-10-22'))

而以下範例描述了如何獲得微秒部分歸零的當前時間戳記:

CURRENT TIMESTAMP - MICROSECOND (current timestamp) MICROSECONDS

如果想將日期或時間值與其他文本相銜接,那麼需要先將該值轉換成字串。
為此,只要使用 CHAR() 函數:

char(current date)
char(current time)
char(current date + 12 hours)

要將字串轉換成日期或時間值,可以使用:

TIMESTAMP ('2002-10-20-12.00.00.000000')
TIMESTAMP ('2002-10-20 12:00:00')
DATE ('2002-10-20')
DATE ('10/20/2002')
TIME ('12:00:00')
TIME ('12.00.00')

TIMESTAMP()、DATE() 和 TIME() 函數接受更多種格式。
上面幾種格式只是範例,我將把它作為一個練習,讓讀者自己去發現其他格式。

有時,您需要知道兩個時間戳記之間的時差。
為此,DB2 提供了一個名為 TIMESTAMPDIFF() 的內置函數。
但該函數返回的是近似值,因為它不考慮閏年,而且假設每個月只有 30 天。
以下範例描述了如何得到兩個日期的近似時差:

timestampdiff (<n>;, char(timestamp('2002-11-30-00.00.00') - timestamp('2002-11-08-00.00.00')))

對於 <n>;,可以使用以下各值來替代,以指出結果的時間單位:

1 = 秒的小數部分
2 = 秒
4 = 分
8 = 時
16 = 天
32 = 周
64 = 月
128 = 季度
256 = 年
當日期很接近時使用 timestampdiff() 比日期相差很大時精確。如果需要進行更精確的計算,可以使用以下方法來確定時差(按秒計):

(DAYS(t1) - DAYS(t2)) * 86400 +  
(MIDNIGHT_SECONDS(t1) - MIDNIGHT_SECONDS(t2))

為方便起見,還可以對上面的方法創建 SQL 用戶定義的函數:

CREATE FUNCTION secondsdiff(t1 TIMESTAMP, t2 TIMESTAMP)
RETURNS INT
RETURN (
  (DAYS(t1) - DAYS(t2)) * 86400 +  
  (MIDNIGHT_SECONDS(t1) - MIDNIGHT_SECONDS(t2))
) @

如果需要確定給定年份是否是閏年,以下是一個很有用的 SQL 函數,您可以創建它來確定給定年份的天數:

CREATE FUNCTION daysinyear(yr INT)
RETURNS INT
RETURN (CASE (mod(yr, 400)) WHEN 0 THEN 366 ELSE
  CASE (mod(yr, 4))   WHEN 0 THEN
  CASE (mod(yr, 100)) WHEN 0 THEN 365 ELSE 366 END
  ELSE 365 END
END)@

最後,以下是一張用於日期操作的內置函數表。
它旨在幫助您快速確定可能滿足您要求的函數,但未提供完整的參考。
有關這些函數的更多資訊,請參考 SQL 參考大全。

SQL 日期和時間函數
DAYNAME
    返回一個大小寫混合的字串,對於參數的日部分,
    用星期表示這一天的名稱(例如,Friday)。
DAYOFWEEK
    返回參數中的星期幾,用範圍在 1-7 的整數值表示,其中 1 代表星期日。
DAYOFWEEK_ISO
    返回參數中的星期幾,用範圍在 1-7 的整數值表示,其中 1 代表星期一。
DAYOFYEAR
    返回參數中一年中的第幾天,用範圍在 1-366 的整數值表示。
DAYS
    返回日期的整數表示。
JULIAN_DAY
    返回從西元前 4712 年 1 月 1 日(儒略日曆的開始日期)到參數中指定日期值之
    間的天數,用整數值表示。
MIDNIGHT_SECONDS
    返回午夜和參數中指定的時間值之間的秒數,用範圍在 0 到 86400 之間的整數值表示。
MONTHNAME
    對於參數的月部分的月份,返回一個大小寫混合的字串(例如,January)。
TIMESTAMP_ISO
    根據日期、時間或時間戳記參數而返回一個時間戳記值。
TIMESTAMP_FORMAT
    從已使用字元範本解釋的字串返回時間戳記。
TIMESTAMPDIFF
    根據兩個時間戳記之間的時差,返回由第一個參數定義的類型表示的估計時差。
TO_CHAR
    返回已用字元範本進行格式化的時間戳記的字元表示。
    TO_CHAR 是 VARCHAR_FORMAT 的同義詞。
TO_DATE 從已使用字元範本解釋過的字串返回時間戳記。
    TO_DATE 是 TIMESTAMP_FORMAT 的同義詞。
WEEK
    返回參數中一年的第幾周,用範圍在 1-54 的整數值表示。
    以星期日作為一周的開始。
WEEK_ISO
    返回參數中一年的第幾周,用範圍在 1-53 的整數值表示。

這些範例回答了我在日期和時間方面所遇到的最常見問題。
如果讀者的回饋中認為我應該用更多範例來更新本文,那麼我會那樣做的。
(事實上,我已經對本文更新了兩次,不是嗎?我要感謝讀者的回饋。)


致謝

Bill Wilkins,DB2 Partner Enablement
Randy Talsma


免責聲明

本文包含樣本代碼。IBM 授予您(“被許可方”)使用這個樣本代碼的非專有的、版權免費的許可證。然而,樣本代碼是以“按現狀”的基礎提供的,不附有任何形式的(不論是明示的,還是默示的)保證,包括對適銷性、適用於某特定用途或非侵權性的默示保證。IBM 及其許可方不對被許可方使用該軟體所導致的任何損失負責。任何情況下,無論損失是如何發生的,也不管責任條款怎樣,IBM 或其許可方都不對由使用該軟體或不能使用該軟體所引起的收入的減少、利潤的損失或資料的丟失,或者直接的、間接的、特殊的、由此產生的、附帶的損失或懲罰性的損失賠償負責,即使 IBM 已經被明確告知此類損害的可能性,也是如此。

關於作者

Paul Yip 是 IBM 多倫多實驗室的資料庫顧問,用於各種分散式平臺的 DB2 就是該實驗室開發的。他的工作主要是幫助公司將應用程式從其他資料庫遷移到 DB2 以及對有經驗的 DBA 講授如何將他們現有的技能運用到 DB2 世界中。他編寫了多篇 DB2 文章和白皮書,並喜歡根據客戶需求來編寫文章。可以通過 ypaul@ca.ibm.com 與 Paul 聯繫

沒有留言:

張貼留言