Як мати автоматичну часову позначку в 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.


5
Це не зовсім еквівалентно часовій позначці SQL Server, оскільки вона базується на системному годиннику; якщо змінити годинник, значення може піти назад. У SQL Server значення часових позначок завжди збільшуються.
Rory MacLeod

26
@Matthieu Немає типу DATETIME даних , але SQLite приймає що-небудь як тип поля .
ЗР.

4
@Matthieu У SQLite згадується тип даних DATETIME у посиланні, яке ви надали. Прочитайте 2.2 Приклади імен спорідненості
Рафік Мухаммед

6
Схоже, це не охоплює заяви UPDATE. Схоже, що тригер - це єдиний спосіб зробити це.
Дейл Андерсон

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;

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


Неможливо додати стовпчик з непостійним за замовчуванням (ALTER TABLE "main". "Xxx_data" ADD COLUMN "created_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)
toing_toing

14

Читання датифункції робочим прикладом автоматичного завершення дати буде:

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 оточені в дужках! Наскільки складно було це показати на одному прикладі?

Веселіться!


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 всередині вашого контекстного класу та додайте цей код API Fluent:

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);

використовуйте "ЗАРАЗ", "локальний час", щоб отримати поточну системну дату, вона відобразить минулий або інший час у вашій базі даних після часу вставки у вашій db.

Дякую тобі...


1
Корисно, якщо вам потрібні мікросекунди; ви можете використовувати DEFAULT (STRFTIME ('% Y-% m-% d% H:% M:% f', 'NOW', 'localtime')) '. Просто кажучи, що DEFAULT CURRENT_TIMESTAMP надасть вам деталізацію лише одну секунду.
Дітмар

Це безумовно працює! зверніть увагу на strroll (), оскільки оточений дужками!
сотник

0

Якщо ви використовуєте браузер SQLite DB, ви можете змінити значення за замовчуванням таким чином:

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.