sqliteデータベースのデフォルトの時間値「今」


190

SQLiteデータベースで、デフォルトのタイムスタンプ列を持つテーブルを作成することはできますDATETIME('now')か?

このような:

CREATE TABLE test (
    id INTEGER PRIMARY KEY AUTOINCREMENT, 
    t TIMESTAMP DEFAULT DATETIME('now')
);

これはエラーになります...解決方法は?

回答:


290

あなたが使えると思います

CREATE TABLE test (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  t TIMESTAMP
  DEFAULT CURRENT_TIMESTAMP
);

バージョン3.1以降(ソース


22
ストレージサイズが心配な場合は、このレシピではタイムスタンプをISO-8601(テキスト形式)で保存し、データベースごとに1日あたり約24バイトを使用することに注意してください。INTEGER(4)列を使用し、 "INSERT INTO test(t)values(strftime("%s "、CURRENT_TIME));"を使用してUNIX時間を保存するだけで、スペースを節約できます。
mckoss

3
@mckossコメントのおかげで、createステートメントは次のようになりました... ... mycolumn default(strftime( '%s'、 'now'))
larham1

1
「...デフォルト(strftime( '%s'、 'now'))」は定数式ではないため、「エラー:列のデフォルト値[...]が定数ではありません」となるデフォルトでは機能しません。
Mirek Rusin 2012

@mckossは素晴らしいですが、SQLiteは「INTEGER」の後ろの「(4)」を無視します。SQLiteのドキュメント:データ型SQLiteバージョン3では、「型名に続く括弧内の数値引数はSQLiteによって無視されます」、および「INTEGER」ストレージクラスの値を格納するために使用されるバイト数は「大きさによって異なります」価値の」。だから、私はあなたがしている権利SQLiteのはわずか4バイトでそれを保存するだろうと思いますが、2038年で、それは6バイト、うまくいけばは、コンピュータは当時、年間4461642.で8バイトでコーディングすることができます使用する必要があるだろう
ma11hew28

94

博士によると 最近のリスト投稿のhipp:

CREATE TABLE whatever(
     ....
     timestamp DATE DEFAULT (datetime('now','localtime')),
     ...
);

どうもありがとうございます!の形式に満足できなかったCURRENT_TIMESTAMPため、エポック以降のマイクロ秒数を返す独自の関数をCで作成しましたDEFAULT。これを今すぐ使用できることをうれしく思います。
マイケル


18

これは、質問に対する他の回答とコメントに基づく完全な例です。この例では、タイムスタンプ(created_at-column)がUNIXエポックとして保存されています UTCタイムゾーン、必要な場合にのみローカルタイムゾーンに変換されます。

UNIXエポックを使用すると、ストレージスペースが節約されます-ISO8601文字列として保存された場合、4バイトの整数と24バイトの文字列の比較。データ型を参照してください。4バイトでは不十分な場合は、6バイトまたは8バイトに増やすことができます。

UTCタイムゾーンでタイムスタンプを保存すると、複数のタイムゾーンで妥当な値を表示するのに便利になります。

SQLiteのバージョンは3.8.6で、Ubuntu LTS 14.04に同梱されています。

$ sqlite3 so.db
SQLite version 3.8.6 2014-08-15 11:46:33
Enter ".help" for usage hints.
sqlite> .headers on

create table if not exists example (
   id integer primary key autoincrement
  ,data text not null unique
  ,created_at integer(4) not null default (strftime('%s','now'))
);

insert into example(data) values
 ('foo')
,('bar')
;

select
 id
,data
,created_at as epoch
,datetime(created_at, 'unixepoch') as utc
,datetime(created_at, 'unixepoch', 'localtime') as localtime
from example
order by id
;

id|data|epoch     |utc                |localtime
1 |foo |1412097842|2014-09-30 17:24:02|2014-09-30 20:24:02
2 |bar |1412097842|2014-09-30 17:24:02|2014-09-30 20:24:02

クエリの時点ではUTC + 2 DSTにいるため、現地時間は正しいです。


7

記憶域を節約するために、REALタイプを使用することをお勧めします。

SQLiteバージョン3のデータ型の 1.2セクションからの引用

SQLiteには、日付や時刻を格納するためのストレージクラスがありません。代わりに、SQLiteの組み込みの日付と時刻関数は、日付、時刻をTEXT、REAL、またはINTEGER値として保存できます。

CREATE TABLE test (
    id INTEGER PRIMARY KEY AUTOINCREMENT, 
    t REAL DEFAULT (datetime('now', 'localtime'))
);

column-constraintを参照してください。

そして挿入任意の値を与えることなく、行。

INSERT INTO "test" DEFAULT VALUES;

1
integer(n)適した値を選択できる場所を選びますn
user272735 2014

4

括弧を書いていないので構文エラーです

あなたが書くなら

datetime( 'now')を選択すると、UTC時間を取得できますが、これを書き込む場合は、この前に括弧を追加する必要があります(datetime( 'now'))for UTC Time。現地時間の場合は同じクエリのdatetime( 'now'、 'localtime')を選択

(datetime( 'now'、 'localtime'))


1

この代替例では、20バイトを節約するためにローカル時間を整数として保存します。作業は、フィールドdefault、Update-trigger、およびViewで行われます。"%s"(二重引用符)は 'Not Constant'エラーをスローしたため、strftimeは '%s'(単一引用符)を使用する必要があります。

Create Table Demo (
   idDemo    Integer    Not Null Primary Key AutoIncrement
  ,DemoValue Text       Not Null Unique
  ,DatTimIns Integer(4) Not Null Default (strftime('%s', DateTime('Now', 'localtime'))) -- get Now/UTC, convert to local, convert to string/Unix Time, store as Integer(4)
  ,DatTimUpd Integer(4)     Null
);

Create Trigger trgDemoUpd After Update On Demo Begin
  Update Demo Set
    DatTimUpd  =                          strftime('%s', DateTime('Now', 'localtime'))  -- same as DatTimIns
  Where idDemo = new.idDemo;
End;

Create View If Not Exists vewDemo As Select -- convert Unix-Times to DateTimes so not every single query needs to do so
   idDemo
  ,DemoValue
  ,DateTime(DatTimIns, 'unixepoch') As DatTimIns -- convert Integer(4) (treating it as Unix-Time)
  ,DateTime(DatTimUpd, 'unixepoch') As DatTimUpd --   to YYYY-MM-DD HH:MM:SS
From Demo;

Insert Into Demo (DemoValue) Values ('One');                      -- activate the field Default
-- WAIT a few seconds --    
Insert Into Demo (DemoValue) Values ('Two');                      -- same thing but with
Insert Into Demo (DemoValue) Values ('Thr');                      --   later time values

Update Demo Set DemoValue = DemoValue || ' Upd' Where idDemo = 1; -- activate the Update-trigger

Select * From    Demo;                                            -- display raw audit values
idDemo  DemoValue  DatTimIns   DatTimUpd
------  ---------  ----------  ----------
1       One Upd    1560024902  1560024944
2       Two        1560024944
3       Thr        1560024944

Select * From vewDemo;                                            -- display automatic audit values
idDemo  DemoValue  DatTimIns            DatTimUpd
------  ---------  -------------------  -------------------
1       One Upd    2019-06-08 20:15:02  2019-06-08 20:15:44
2       Two        2019-06-08 20:15:44
3       Thr        2019-06-08 20:15:44
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.