首頁>Club>
4
回覆列表
  • 1 # 大國師魂系列

    sqlite日期型別掌握最主要要明白timestamp使用。

    timestamp兩種屬性:

    自動初始化: 此行為只在第一次寫入資料時,怎麼把時間設為當前時間. (DEFAULT CURRENT_TIMESTAMP)

    自動更新: 此行為在修改資料時,會自動幫你把值修改為當前時間. (ON UPDATE CURRENT_TIMESTAMP)

    自動初始化 第一次寫入資料時把時間設為當前時間 tiims1 TIMESTAMP DEFAULT CURRENT_TIMESTAMP

    自動更新 每一次寫入資料時把時間設為當前時間 ON UPDATE CURRENT_TIMESTAMP

    timestamp兩種結合 系統預設 自動初始化以及自動更新 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

    四種狀態:由上面兩種屬性延伸出四種狀態

    自動初始化以及自動更新 timestamp欄位的資料預設就是此行為

    ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

    只做初始化,更新時不自動更新 ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP

    只做自動更新,不做初始化 ts TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP

    什麼都不做 datetime

    下面這些語句是等效的:

    CREATE TABLE t (ts TIMESTAMP);

    CREATE TABLE t (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP

    ON UPDATE CURRENT_TIMESTAMP);

    CREATE TABLE t (ts TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

    DEFAULT CURRENT_TIMESTAMP);

    ts TIMESTAMP DEFAULT 0 //只是給一個常量(注:0000-00-00 00:00:00)

    可以在TIMESTAMP列的定義中包括NULL屬性以允許列包含NULL值。例如:

    CREATE TABLE t

    (

    ts1 TIMESTAMP NULL DEFAULT NULL,

    ts2 TIMESTAMP NULL DEFAULT 0,

    ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP

    );

    未指定NULL屬性,將列設定為NULL,用於將它設定為當前的時間戳。

    注意允許NULL值的TIMESTAMP列不會採用當前的時間戳,除非要麼其 預設值定義為CURRENT_TIMESTAMP,或者NOW()或CURRENT_TIMESTAMP被插入到該列內。換句話說,只有使用如下建立,定義為 NULL的TIMESTAMP列才會自動更新:

    CREATE TABLE t (ts NULL DEFAULT CURRENT_TIMESTAMP);

    CREATE TABLE t1 (ts NULL DEFAULT NULL);

    CREATE TABLE t2 (ts NULL DEFAULT "0000-00-00 00:00:00");

    則必須顯式插入一個對應當前日期和時間的值。例如:

    INSERT INTO t1 VALUES (NOW());

    INSERT INTO t2 VALUES (CURRENT_TIMESTAMP);

    sqlite3支援的資料型別:

    NULL、INTEGER、REAL、TEXT、BLOB

    但是,sqlite3也支援如下的資料型別

    smallint 16位整數

    integer 32位整數

    decimal(p,s) p是精確值,s是小數位數

    float 32位實數

    double 64位實數

    char(n) n長度字串,不能超過254

    varchar(n) 長度不固定最大字串長度為n,n不超過4000

    graphic(n) 和 char(n) 一樣,但是單位是兩個字元double-bytes,n不超過127(中文字)

    vargraphic(n) 可變長度且最大長度為n

    date 包含了年份、月份、日期

    time 包含了小時、分鐘、秒

    timestamp 包含了年、月、日、時、分、秒、千分之一秒

    sqlite3支援的函式

    【1】日期函式

    datetime() : 產生日期和時間

    date(): 產生日期

    time():產生時間

    strftime():對以上3個函式產生的日期和時間進行格式化

    用法例項:

    1、SELECT date("2011-9-9","+1 day","+1 year"); 結果是 2010-09-10

    2、SELECT datetime("now"); 當前日期和時間

    3、SELECT datetime("now", "start of month"); 本月的第一天零點,也可以設定年和日的第一天

    4、SELECT datetime("now","+1 hour","-12 minute"); 當前時間加48分鐘

    如果需要精確到毫秒,使用

    select strftime("%Y-%m-%d %H:%M:%f","now")

    結果:2017-04-12 17:48:35.890

    strftime() 函式可以將 YYYY-MM-DD HH:MM:SS 格式的日期字串轉換為其它形式的字串

    %d:天數,01-31

    %f :小數形式的秒,SS.SSS

    %H:小時

    %j :某一天是該年的第幾天,001-366

    %m:月份,00-12

    %M:分鐘,00-59

    %s:從1970到現在的秒數

    %S:秒,00-59

    %w:星期,0-6,0是星期天

    %W:某天是該年的第幾周,01-53

    %Y:年,YYYY

    %% 百分號

    樣本表:job_history

    employee_id start_date end_date job_id department_id

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

    102 1993-01-13 1998-07-24 IT_PROG 60

    101 1989-09-21 1993-10-27 AC_ACCOUNT 110

    101 1993-10-28 1997-03-15 AC_MGR 110

    201 1996-02-17 1999-12-19 MK_REP 20

    114 1998-03-24 1999-12-31 ST_CLERK 50

    122 1999-01-01 1999-12-31 ST_CLERK 50

    200 1987-09-17 1993-06-17 AD_ASST 90

    176 1998-03-24 1998-12-31 SA_REP 80

    176 1999-01-01 1999-12-31 SA_MAN 80

    200 1994-07-01 1998-12-31 AC_ACCOUNT 90

    如果我們想從表job_history中查詢start_date的年,月和日值,則可以使用以下SQL。

    SELECT start_date,strftime("%Y",start_date) as "Year",

    strftime("%m",start_date) as "Month",

    strftime("%d",start_date) as "Day"

    FROM job_history;

    結果

    start_date年月日

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

    1993-01-13 1993 01 13

    1989-09-21 1989 09 21

    1993-10-28 1993 10 28

    1996-02-17 1996 02 17

    1998-03-24 1998 03 24

    1999-01-01 1999 01 01

    1987-09-17 1987 09 17

    1998-03-24 1998 03 24

    1999-01-01 1999 01 01

    1994-07-01 1994 07 01

    樣本表:job_history

    employee_id start_date end_date job_id department_id

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

    102 1993-01-13 1998-07-24 IT_PROG 60

    101 1989-09-21 1993-10-27 AC_ACCOUNT 110

    101 1993-10-28 1997-03-15 AC_MGR 110

    201 1996-02-17 1999-12-19 MK_REP 20

    114 1998-03-24 1999-12-31 ST_CLERK 50

    122 1999-01-01 1999-12-31 ST_CLERK 50

    200 1987-09-17 1993-06-17 AD_ASST 90

    176 1998-03-24 1998-12-31 SA_REP 80

    176 1999-01-01 1999-12-31 SA_MAN 80

    200 1994-07-01 1998-12-31 AC_ACCOUNT 90

    如果我們想從表job_history中查詢在第一季度加入的員工的start_date的年,月和日值,則可以使用以下SQL。

    SELECT start_date,strftime("%Y",start_date) as "Year",

    strftime("%m",start_date) as "Month",

    strftime("%d",start_date) as "Day"

    FROM job_history

    WHERE strftime("%m",start_date)

    IN("01","02","03");

    結果

    start_date年月日

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

    1993-01-13 1993 01 13

    1996-02-17 1996 02 17

    1998-03-24 1998 03 24

    1999-01-01 1999 01 01

    1998-03-24 1998 03 24

    1999-01-01 1999 01 01

    應用舉例:

    SELECT strftime("%Y.%m.%d %H:%M:%S","now","localtime");

    結果:2020.01.01 01:41:09

    其實更好的用法是這樣的,比如統,本月或本年的支出:

    select strftime("%Y-%m",日期) as 月份,sum(支出) as 月支出 from 流水帳 group by 月份;

    SQLite包含了如下時間/日期函式:

    datetime().......................產生日期和時間

    date()...........................產生日期

    time()...........................產生時間

    strftime().......................對以上三個函式產生的日期和時間進行格式化

    datetime()的用法是:datetime(日期/時間,修正符,修正符...)

    date()和time()的語法與datetime()相同。

    在時間/日期函數里可以使用如下格式的字串作為引數:

    YYYY-MM-DD

    YYYY-MM-DD HH:MM

    YYYY-MM-DD HH:MM:SS

    YYYY-MM-DD HH:MM:SS.SSS

    HH:MM

    HH:MM:SS

    HH:MM:SS.SSS

    now

    其中now是產生現在的時間。

    舉例(寫這個筆記的時間是2006年10月17日晚8點到10點,測試環境:SQLite 2.8.17,WinXP,臺北時間):

    例1.

    select datetime("now");

    結果:2006-10-17 12:55:54

    例2.

    select datetime("2006-10-17");

    結果:2006-10-17 12:00:00

    例3.

    select datetime("2006-10-17 00:20:00","+1 hour","-12 minute");

    結果:2006-10-17 01:08:00

    例4.

    select date("2006-10-17","+1 day","+1 year");

    結果:2007-10-18

    例5.

    select datetime("now","start of year");

    結果:2006-01-01 00:00:00

    例6.

    select datetime("now","start of month");

    結果:2006-10-01 00:00:00

    例7.

    select datetime("now","start of day");

    結果:2006-10-17 00:00:00

    例8.

    select datetime("now","+10 hour","start of day","+10 hour");

    結果:2006-10-17 10:00:00

    例9.

    select datetime("now","localtime");

    結果:2006-10-17 21:21:47

    例10.

    select datetime("now","+8 hour");

    結果:2006-10-17 21:24:45

    例3中的+1 hour和-12 minute表示可以在基本時間上(datetime函式的第一個引數)增加或減少一定時間。

    例5中的start of year表示一年開始的時間。

    從例8可以看出,儘管第2個引數加上了10個小時,但是卻被第3個引數“start of day”把時間歸零到00:00:00,隨後的第4個引數在00:00:00

    的基礎上把時間增加了10個小時變成了10:00:00。

    例9把格林威治時區轉換成本地時區。

    例10把格林威治時區轉換成東八區。

    strftime()函式可以把YYYY-MM-DD HH:MM:SS格式的日期字串轉換成其它形式的字串。

    strftime()的語法是strftime(格式, 日期/時間, 修正符, 修正符, ...)

    它可以用以下的符號對日期和時間進行格式化:

    %d 月份, 01-31

    %f 小數形式的秒,SS.SSS

    %H 小時, 00-23

    %j 算出某一天是該年的第幾天,001-366

    %m 月份,00-12

    %M 分鐘, 00-59

    %s 從1970年1月1日到現在的秒數

    %S 秒, 00-59

    %w 星期, 0-6 (0是星期天)

    %W 算出某一天屬於該年的第幾周, 01-53

    %Y 年, YYYY

    %% 百分號

    strftime()的用法舉例如下:

    例11.

    select strftime("%Y.%m.%d %H:%M:%S","now","localtime");

    結果:2006.10.17 21:41:09

    例11用圓點作為日期的分隔附,並把時間轉換為當地的時區的時間。

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

    select datetime("2015-06-10 11:17:00","+1 day","-1 hour","-10 minute","+1 year","start of day","+1 hour");

    注意前面的條件會被後面的覆蓋.

    sqlite> select strftime("%Y-%m-%d %H:%M:%S","now","localtime");

    注意格式化時要使用指定的%符號,其實相當於c裡面的sprintf

    儲存日期和時間資料型別:

    SQLite沒有專門提供儲存日期和時間儲存型別,通常可以TEXT , REAL和INTEGER型別來替代的方式儲存。

    TEXT對應的資料:"YYYY-MM-DD HH:MM:SS.SSS"格式的資料

    REAL對應的資料: Julian日期格式儲存,即從公元前 4714 年 11 月 24 日格林尼治時間的正午開始算起的天數。

    INTEGER對應的資料:Unix時間形式的資料 , 即從 1970-01-01 00:00:00 UTC 算起的秒數。

    可以以任何上述格式來儲存日期和時間,並且可以使用內建的日期和時間函式來自由轉換不同格式。

    二、【算術函式】

    abs(X):返回絕對值

    max(X,Y[,...]):返回最大值

    min(X,Y,[,...]):返回最小值

    random(*):返回隨機數

    round(X[,Y]): 四捨五入

    三、【字串處理函式】

    length(x) :返回字串字元個數

    lower(x) :大寫轉小寫

    upper(x):小寫轉大寫

    substr(x,y,Z):擷取子串

    like(A,B):確定給定的字串與指定的模式是否匹配

    四、【條件判斷函式、集合函式、其它函式】

    typeof(x):返回資料的型別

    last_insert_rowid():返回最後插入的資料的ID

    ************ *************************************

    sqlite3提供了C函式介面來操作sqlite3資料庫,其中有個關鍵資料結構 sqlite3 * 型別

    1、開啟資料庫

    int sqlite3_open(檔名,sqlite3 **); - 檔名若不存在,則會自動建立

    返回SQLITE_OK表示操作正常,這些宏的定義在sqlite3.h檔案中定義,看原始碼會懂的更多

    2、關閉資料庫

    int sqlite3_close(sqlite3 *);

    3、SQL語句操作

    int sqlite3_exec(sqlite3 *,const char *sql, sqlite3_callback,void *,char **errmsg);

    這就是執行一條sql語句的函式

    引數1:open函式得到的指標

    引數2:一條sql語句,以"\0"結尾

    引數3:sqlite3_callback是回撥,當這條語句執行後,sqlite3會呼叫你提供的這個函式,回撥函式要查閱資料

    引數4:void *是自己提供的指標,可以傳遞任何指標到這裡,這個引數最終會傳到回撥函數里面,如果不需要

    傳到回撥函數里面,則可以設定為NULL

    引數5:錯誤資訊,當執行失敗時,可以查閱這個指標,可以利用printf("%s\n",errmsg)得到一串字串資訊,

    該資訊表明出錯的地方

    通常,sqlite3_callback和void *都設定為NULL,表示不需要回調,比如做insert、delete操作,就沒有必要使用回撥,而當使用select時,就要使用回撥,因為sqlite3把資料查出來,得透過回撥來說明查出什麼資料

    注意sqlite3和java的整數資料型別的區別

    sqlite3的資料型別和java資料型別對應上要小心,特別是整數型別。

    java 中int型別4位儲存,範圍 -2^31到2^31-1,即-2147483648到2147483647

    java 中long型別8位儲存,範圍-2^63到2^63-1,即--9223372036854775808到9223372036854775807

    sqlite3的integer型別用1, 2, 3, 4, 6, or 8位儲存。原文:

    INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value.

    所以java中byte,short,int,long型別表示的範圍都在sqlite3的integer類型範圍中。

    現在可以看到sqlite3的integer不等於java的integer型別,因為表示範圍不同。

    如果sqlite3的integer型別表示的範圍在-2147483648到2147483647間,那麼java對應的用integer型別也可以,如果sqlite3的integer型別表示的範圍超過了-2147483648到2147483647間,而位於-9223372036854775808到9223372036854775807間,那麼java就必須用long型別表示。

    Timestamp(時間戳)計算的小問題,注意將其強制轉換為long。Hibernate時間段查詢。

    Timestamp的計算一般是先使用gettime()將其轉化為long再計算。

    如下面這個例子:

    複製程式碼

    Timestamp begin = new java.sql.Timestamp((new java.util.Date()).getTime());

    java.sql.Timestamp end = new Timestamp(0);

    long intime=begin.getTime();

    long endtime=intime+((long)RemindDay*1000*24*60*60);//注意將在RemindDay前加上(long)強制型別轉換。

    end.setTime(endtime);

    複製程式碼

    是求將當前時間加上RemindDay天后的Timestamp。在沒有加強制型別轉換的情況下,當Timestamp>=25時,計算就會出錯。

    因為“RemindDay*1000*24*60*60”都是int型別,其結果也預設是int型別,但是Timestamp>=25時其結果會超過int的最大限制。

    所以加個(long)強制型別轉換就可以了。

    順便提一下:

    使用hibernate查詢在一段時間內的資料hql語句。

  • 中秋節和大豐收的關聯?
  • 風行天下的成語解釋?