จะมีการประทับเวลาอัตโนมัติใน 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คำสั่งอย่างชัดเจนชุดข้อมูลนี้ไปก็จะถูกตั้งค่าNULLNULL


5
นั่นไม่เทียบเท่ากับการประทับเวลาของ SQL Server เพราะมันขึ้นอยู่กับนาฬิกาของระบบ หากคุณเปลี่ยนนาฬิกาค่าอาจย้อนกลับได้ ใน SQL Server ค่าการประทับเวลาจะเพิ่มขึ้นเสมอ
Rory MacLeod

26
@ Matthieu ไม่มีชนิดDATETIME ข้อมูลแต่ SQLite ยอมรับสิ่งใดเป็นประเภทฟิลด์
CL.

4
@Matthieu มีประเภทข้อมูล DATETIME ที่กล่าวถึงใน SQLite ในลิงค์ที่คุณให้ไว้ อ่าน 2.2 ตัวอย่างชื่อผู้สนใจ
Rafique Mohammed

6
ดูเหมือนจะไม่ครอบคลุมงบ UPDATE ดูเหมือนทริกเกอร์จะเป็นวิธีเดียวที่จะทำได้
Dale Anderson

2
@CL ขออภัยคุณพูดถูก ฉันผสานคำตอบและคำตอบของคุณไม่ถูกต้อง ด้วยDEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime'))หนึ่งได้รับจริงค่ามิลลิมีความหมาย
Dietmar

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

การอ่านdatefuncตัวอย่างการทำงานของการเสร็จสิ้นวันที่และเวลาอัตโนมัติจะเป็น:

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 ให้ตกแต่งคุณสมบัติด้วย Data Annotation [Timestamp] จากนั้นไปที่ OnModelCreating ที่ถูกแทนที่ภายในคลาสบริบทของคุณและเพิ่มโค้ด Fluent API นี้:

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

มันจะสร้างค่าเริ่มต้นให้กับทุกข้อมูลที่จะแทรกลงในตารางนี้


รู้ว่าเอนทิตีทำงานอย่างไรบน Android ในแอป Xamarin? ยังไม่ได้ทำการทดสอบแม้ว่าจะเป็นการดีที่จะแทนที่ DAL ด้วย
samis

ฉันไม่พบแพ็คเกจที่จำเป็นสำหรับ sqliteHasDefault คุณรู้หรือไม่ว่าฉันต้องซื้อแพ็คเกจใดจาก nuget?
Simons0n

@ Simons0n ลองใช้ Namespace ของ Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder
Rafael

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
มีประโยชน์หากคุณต้องการไมโครวินาที คุณสามารถใช้ค่าเริ่มต้น (STRFTIME ('% Y-% m-% d% H:% M:% f', 'NOW', 'localtime')) " การพูดว่า DEFAULT CURRENT_TIMESTAMP จะทำให้คุณมีรายละเอียดเพียงหนึ่งวินาที
Dietmar

ได้ผลแน่นอน! ให้ความสนใจกับ strftime () ตามที่ล้อมรอบด้วยวงเล็บ!
centurian

0

หากคุณใช้ SQLite DB-Browser คุณสามารถเปลี่ยนค่าเริ่มต้นได้ด้วยวิธีนี้:

  1. เลือกโครงสร้างฐานข้อมูล
  2. เลือกตาราง
  3. แก้ไขตาราง
  4. ในคอลัมน์ของคุณให้อยู่ภายใต้ 'ค่าเริ่มต้น' ค่า: = (วันที่และเวลา ('now', 'localtime'))

ฉันขอแนะนำให้ทำการอัปเดตฐานข้อมูลของคุณก่อนเนื่องจากรูปแบบที่ไม่ถูกต้องในค่าอาจทำให้เกิดปัญหาใน SQLLite Browser

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.