Значение базы данных по умолчанию для базы данных sqlite 'now'

Возможно ли, чтобы в базе данных sqlite появилась таблица, в которой есть столбец временной метки, который по умолчанию равен DATETIME('now')?

Вот так:

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

Это дает ошибку... Как решить?

Ответ 1

Я считаю, что вы можете использовать

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

по версии 3.1 (источник)

Ответ 2

согласно dr. hipp в недавнем списке сообщений:

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

Ответ 3

Это просто синтаксическая ошибка, вам нужны скобки: (DATETIME('now'))

Если вы посмотрите на документацию, вы заметите скобку, которая добавляется вокруг опции 'expr' в синтаксисе.

Ответ 4

Это полный пример, основанный на других ответах и ​​комментариях к вопросу. В примере временная метка (created_at -column) сохраняется как unix epoch Часовой пояс UTC и преобразуется в локальный часовой пояс только при необходимости.

Использование unix-эпохи сохраняет пространство памяти - 4 байта целых по сравнению с строкой 24 байта при сохранении как строка ISO8601, см. типы данных. Если 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 в момент запроса.

Ответ 5

Может быть лучше использовать тип REAL, чтобы сэкономить место для хранения.

Цитата из 1.2 раздела Типы данных в SQLite версии 3

SQLite не имеет класса хранения, выделенного для хранения дат и/или времени. Вместо этого встроенные функции даты и времени в SQLite могут сохранять даты и время в виде значений TEXT, REAL или INTEGER.

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

см. ограничение столбца.

И вставьте строку без указания какого-либо значения.

INSERT INTO "test" DEFAULT VALUES;

Ответ 6

Это синтаксическая ошибка, потому что вы не указали скобки

если вы пишете

Выберите дату и время ('now') то это даст вам время utc, но если вы это напишете запрос, вы должны добавить скобки перед этим поэтому (datetime ('now')) для UTC Time. для локального времени такое же Выберите дату и время ( "сейчас", "местное время" ) для запроса

(DateTime ( 'теперь', 'LocalTime'))

Ответ 7

Этот альтернативный пример хранит местное время как целое число, чтобы сохранить 20 байтов. Работа сделана в полях default, Update-trigger и View. strftime должен использовать "% s" (одинарные кавычки), потому что "% 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 vewDemo;                                            -- display automatic audit values