Как иметь автоматическую метку времени в SQLite?

132

У меня есть база данных SQLite версии 3, и я использую C # для создания приложения, которое использует эту базу данных.

Я хочу использовать поле временной отметки в таблице для параллелизма, но я замечаю, что когда я вставляю новую запись, это поле не устанавливается и является нулевым.

Например, в MS SQL Server, если я использую поле метки времени, которое обновляется базой данных, я не должен устанавливать его самостоятельно. это возможно в SQLite?

Альваро Гарсия
источник

Ответы:

212

Просто объявите значение по умолчанию для поля:

CREATE TABLE MyTable(
    ID INTEGER PRIMARY KEY,
    Name TEXT,
    Other STUFF,
    Timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);

Однако, если ваша INSERTкоманда явно устанавливает это поле в NULL, оно будет установлено в NULL.

CL.
источник
5
Это не совсем эквивалентно временной отметке SQL Server, поскольку она основана на системных часах; если вы измените часы, значение может вернуться назад. В SQL Server значения отметок времени всегда увеличиваются.
Рори МакЛауд
26
@Matthieu Тип DATETIME данных отсутствует , но SQLite принимает все как тип поля .
кл.
4
@Matthieu Существует тип данных DATETIME, упомянутый в SQLite в ссылке, которую вы предоставили. Прочитайте 2.2 Примеры
названий
6
Это, кажется, не покрывает заявления ОБНОВЛЕНИЯ. Похоже, триггер - единственный способ сделать это.
Дейл Андерсон
2
@CL Извините, вы правы. Я неправильно слил твой ответ и ответ Джаведа. С DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime'))одного на самом деле получаются значимые микросекундные значения.
Дитмар
71

Вы можете создать поле TIMESTAMP в таблице на SQLite, смотрите это:

CREATE TABLE my_table (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    name VARCHAR(64),
    sqltime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);

INSERT INTO my_table(name, sqltime) VALUES('test1', '2010-05-28T15:36:56.200');
INSERT INTO my_table(name, sqltime) VALUES('test2', '2010-08-28T13:40:02.200');
INSERT INTO my_table(name) VALUES('test3');

Вот результат:

SELECT * FROM my_table;

введите описание изображения здесь

mr.boyfox
источник
Невозможно добавить столбец с непостоянным значением по умолчанию (ALTER TABLE "main". "Xxx_data" ADD COLUMN "creation_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)
toing_toing
14

Чтение datefunc рабочим примером автоматического завершения datetime будет:

sqlite> CREATE TABLE 'test' ( 
   ...>    'id' INTEGER PRIMARY KEY,
   ...>    'dt1' DATETIME NOT NULL DEFAULT (datetime(CURRENT_TIMESTAMP, 'localtime')), 
   ...>    'dt2' DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime')), 
   ...>    'dt3' DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now', 'localtime'))
   ...> );

Давайте вставим несколько строк таким образом, чтобы инициировать автоматическое завершение даты и времени:

sqlite> INSERT INTO 'test' ('id') VALUES (null);
sqlite> INSERT INTO 'test' ('id') VALUES (null);

Сохраненные данные ясно показывают, что первые два одинаковы, но не третья функция:

sqlite> SELECT * FROM 'test';
1|2017-09-26 09:10:08|2017-09-26 09:10:08|2017-09-26 09:10:08.053
2|2017-09-26 09:10:56|2017-09-26 09:10:56|2017-09-26 09:10:56.894

Обратите внимание, что функции SQLite заключены в круглые скобки! Насколько сложно было показать это на одном примере?

Радоваться, веселиться!

Centurian
источник
7

Вы можете использовать триггеры. работает очень хорошо

CREATE TABLE MyTable(
ID INTEGER PRIMARY KEY,
Name TEXT,
Other STUFF,
Timestamp DATETIME);


CREATE TRIGGER insert_Timestamp_Trigger
AFTER INSERT ON MyTable
BEGIN
   UPDATE MyTable SET Timestamp =STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') WHERE id = NEW.id;
END;

CREATE TRIGGER update_Timestamp_Trigger
AFTER UPDATE On MyTable
BEGIN
   UPDATE MyTable SET Timestamp = STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') WHERE id = NEW.id;
END;
Рахмат Анджираби
источник
6

Чтобы дополнить ответы выше ...

Если вы используете EF, украсьте свойство аннотацией данных [Timestamp], затем перейдите к переопределенной OnModelCreating внутри вашего контекстного класса и добавьте следующий код Fluent API:

modelBuilder.Entity<YourEntity>()
                .Property(b => b.Timestamp)
                .ValueGeneratedOnAddOrUpdate()
                .IsConcurrencyToken()
                .ForSqliteHasDefaultValueSql("CURRENT_TIMESTAMP");

Он установит значение по умолчанию для всех данных, которые будут вставлены в эту таблицу.

Рафаэль
источник
Знаете, как Entity работает на Android, в приложении Xamarin? Не успел пройти тестирование, хотя было бы неплохо заменить DAL на.
Сами
Я не нашел пакет, который нужен для sqliteHasDefault. Вы знаете, какой пакет мне нужно получить от nuget?
Simons0n
@ Simons0n, попробуйте использовать это пространство имен Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.
Рафаэль
2

вы можете использовать настраиваемую дату и время, используя ...

 create table noteTable3 
 (created_at DATETIME DEFAULT (STRFTIME('%d-%m-%Y   %H:%M', 'NOW','localtime')),
 title text not null, myNotes text not null);

используйте «NOW», «localtime», чтобы получить текущую системную дату, иначе она покажет прошлое или другое время в вашей базе данных после времени вставки в вашу базу данных.

Спасибо вам...

Джавед
источник
1
Полезно, если нужны микросекунды; вы можете использовать DEFAULT (STRFTIME ('% Y-% m-% d% H:% M:% f', 'NOW', 'localtime')) `. Просто скажите DEFAULT CURRENT_TIMESTAMP, и вы получите детализацию в одну секунду.
Dietmar
Это определенно работает! обратите внимание на strftime (), поскольку он заключен в круглые скобки!
центуриан
0

Если вы используете SQLite DB-Browser, вы можете изменить значение по умолчанию следующим образом:

  1. Выберите структуру базы данных
  2. выберите стол
  3. изменить таблицу
  4. в столбце укажите значение по умолчанию: = (datetime ('now', 'localtime'))

Я рекомендую сделать обновление базы данных раньше, потому что неправильный формат значения может привести к проблемам в браузере SQLLite.

SJX
источник