Значение по умолчанию для базы данных sqlite «сейчас»

138

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

Вот так:

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

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

Теги:

6 ответов

227
Лучший ответ

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

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

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

  • 19
    Если вас беспокоит размер хранилища, обратите внимание, что этот рецепт сохранит ваши временные метки в формате ISO-8601 (текстовый формат), занимая в базе данных около 24 байт на дату. Вы можете сэкономить место, просто используя столбец INTEGER (4) и сохраняя время Unix с помощью значений INSERT INTO test (t) (strftime ("% s", CURRENT_TIME)); "
  • 2
    @mckoss благодаря вашему комментарию оператор create стал: ... mycolumn default (strftime ('% s', 'now'))
Показать ещё 2 комментария
72

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

CREATE TABLE whatever(
     ....
     timestamp DATE DEFAULT (datetime('now','localtime')),
     ...
);
  • 0
    спасибо - мне было интересно, как создать временную метку по умолчанию с местным временем, а не с UTC
  • 0
    Metoo, спасибо за параметр местного времени
Показать ещё 2 комментария
32

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

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

8

Это полный пример, основанный на других ответах и ​​комментариях к вопросу. В примере временная метка (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 в момент запроса.

3

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

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

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

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

2

Возможно, лучше использовать тип 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 строка без предоставления каких-либо значений.

INSERT INTO "test" DEFAULT VALUES;
  • 1
    Я предпочитаю integer(n) где можно выбрать подходящее значение для n .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню