1. SQLite nested transaction

    遇到 SQLite 需要 nested transaction 的情況,查了一下,似乎沒辦法直接用 TRANSACTION 做。後來是看到另外一個語法 SAVEPOINT 可以解決這樣的問題,而且一般的 SQL DB 好像也都支援。以下是相關的用法:

    SAVEPOINT savepoint_name
    
    RELEASE savepoint_name
    
    ROLLBACK TO SAVEPOINT savepoint_name
    

    savepoint_name 就取自己要的名稱,需要做 nested 的情況下就用不同的 savepoint_name,也可以外層用 SAVEPOINT,內層用 TRANSACTION;但是不能外層是 TRANSACTION,內層用 SAVEPOINT 這樣。

    參考資料:


  2. SQLite datetime group by

    SQLite 裡的 datetime 其實也只是 string 而已,所以用的方式跟 MySQL 之類的不同,MySQL 可以直接 Date(xxx) 或是 Month(xxx) 之類的做擷取,不過 SQLite 要用 strftime 來做,例如:

    SELECT strftime('%Y',datetime) AS year, 
       strftime('%m',datetime) AS month, 
       sum(amount) AS Amount 
    FROM mytable 
    GROUP BY year
    

    Ref:


  3. C SQLite Transaction

    sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
    
    // if error
    sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
    
    //else
    sqlite3_exec(db, "END TRANSACTION;", NULL, NULL, NULL);
    

    如果中間發生錯誤,就單做 ROLLBACK 就好, 不需要再做 END TRANSACTION,下面 ref 第二篇裡面的邏輯有點問題,做了 ROLLBACK 然後 break 出去之後又做 COMMIT,怪怪的。

    Ref:


  4. SQLite Foreign Key Support

    SQLite 在設定完 foreign key 之後,對 foreign key 的限制卻沒有生效,例如有一個 table 只有 id=1,但是我在另外一個 table 參照這個 table,並加入 foreign key id=2,是會過的,但是應該是要擋掉才對。查了一下,發現預設並不會開啟= =|||。所以必須在每次的 DB connection 時,都需要做一次這個動作:

    PRAGMA foreign_keys = ON;
    

    直接用 sqlite3_exec 之類的執行就可以了。

    Ref:


  5. SQLite datetime

    一開始以為只要直接 insert timestmap,它就會自動幫我轉,不過好像沒那麼簡單...,原本我是用以下語法:

    INSERT INTO tbl(tx_bytes, rx_bytes, timestamp) VALUES(?, ?, ?);
    

    timestamp 這裏是 datetime type,可是當我要比較時間的時候:

    SELECT * FROM tbl WHERE timestamp >= '2015-01-01' AND timestamp < '2015-02-01';
    

    結果會完全沒任何東西,後來查了一下,發現它存的時候是用字串存囧,在輸入之前需要自己做轉換,所以會變成:

    INSERT INTO data_planner(tx_bytes, rx_bytes, timestamp) VALUES(?, ?, datetime(?, 'unixepoch', 'localtime'));
    

    localtime 表示轉成自己所在的時區,不然預設會在 utc+0

    Ref:
    How ...


Page 1 / 1