2011-07-05 36 views
18

Tôi muốn cập nhật một trường có dấu thời gian hiện tại bất cứ khi nào hàng được cập nhật.khi cập nhật current_timestamp với SQLite

Trong MySQL tôi sẽ làm gì, khi tuyên bố bảng

LastUpdate TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP 

Nhưng "trên bản cập nhật" một phần không làm việc với SQLite. Tôi không thể tìm cách tự động làm điều đó, tôi có cần khai báo trình kích hoạt không?

EDIT: Đối với hồ sơ, đây là kích hoạt hiện tại của tôi:

CREATE TRIGGER [UpdateLastTime] 
AFTER UPDATE 
ON Package 
FOR EACH ROW 
BEGIN 
UPDATE Package SET LastUpdate = CURRENT_TIMESTAMP WHERE ActionId = old.ActionId; 
END 

Cảm ơn

+2

Để chuyên gia SQLite: đừng ngại để gửi "bạn phải viết một cò" nếu đó là câu trả lời. –

+3

Nếu bạn đang tự hỏi 'ActionId' và' old.ActionId' đến từ đâu, 'ActionId' là một cột trong bảng Package của Jonas, và' old' được định nghĩa bởi SQLite như là một tham chiếu đến các hàng được cập nhật. (Xem: http://www.sqlite.org/lang_createtrigger.html) – Arel

Trả lời

16

Có, bạn cần phải sử dụng một cò. (Chỉ cần kiểm tra: là trình kích hoạt đã đăng của bạn có hoạt động chính xác không? Thoạt nhìn, có vẻ ổn với tôi.)

Một lối tắt đơn độc nhất vô nhị của MySQL. Đó là những gì nó được; cấu trúc này không thể được sử dụng tương tự cho bất kỳ giá trị nào khác hoặc cho bất kỳ loại cột nào khác ngoài TIMESTAMP. (Lưu ý cách chức năng này được xác định trên TIMESTAMP type page thay vì CREATE TABLE page, vì chức năng này dành riêng cho các cột TIMESTAMP và không phải là CREATE TABLE báo cáo nói chung.) Cũng cần lưu ý rằng mặc dù nó dành riêng cho loại TIMESTAMP, SQLite doesn't even have distinct date/time types.

Theo như tôi biết, không có RDBMS nào khác cung cấp lối tắt này thay vì sử dụng trình kích hoạt thực tế. Từ những gì tôi đã đọc, trình kích hoạt phải được sử dụng để thực hiện điều này trên MS SQL, SQLite, PostgreSQL và Oracle.


Một lưu ý cuối cùng cho người qua đường:

này không phải là để bị nhầm lẫn với ON UPDATE khoản liên quan đến ràng buộc khoá ngoại. Đó là một cái gì đó hoàn toàn khác nhau, mà có khả năng tất cả các RDBMS hỗ trợ các ràng buộc khoá ngoại có (bao gồm cả MySQL và SQLite).

+0

Cảm ơn bạn đã trả lời toàn diện! (Có trình kích hoạt hoạt động tốt :)) – Jonas

+0

Đối với tôi, có vẻ như trình kích hoạt này dẫn đến vòng lặp vô hạn. Bản thân trình kích hoạt sẽ kích hoạt bản cập nhật mới. Và bản cập nhật mới sẽ kích hoạt lại trình kích hoạt. Và một lần nữa và một lần nữa. –

+0

@John Smith Tùy chọn: Có thể là không. http://www.sqlite.org/pragma.html#pragma_recursive_triggers –

2

John chính xác về cài đặt SQLite mặc định, trình kích hoạt này dẫn đến vòng lặp vô hạn. Để tránh đệ quy, sử dụng mệnh đề WHEN.

Tiếp theo sẽ làm việc ngay cả khi thiết lập recursive_triggers là:

PRAGMA recursive_triggers=1;  --- test 

CREATE TRIGGER [UpdateLastTime] 
    AFTER UPDATE 
    ON package 
    FOR EACH ROW 
    WHEN NEW.LastUpdate < OLD.LastUpdate --- this avoid infinite loop 
BEGIN 
    UPDATE Package SET LastUpdate=CURRENT_TIMESTAMP WHERE ActionId=OLD.ActionId; 
END; 
+0

Câu hỏi này đã được đăng gần 4 năm trước. Có lẽ mọi thứ đã thay đổi. Nó làm việc tốt trở lại sau đó. – Jonas

0
-- Describe UPDATELASTTIME 
CREATE TRIGGER [UpdateLastTime] 
    AFTER 
    UPDATE 
    ON test 
    FOR EACH ROW 
    WHEN NEW.last_update_ts <= OLD.last_update_ts 
BEGIN 
    update test set last_update_ts=CURRENT_TIMESTAMP where id=OLD.id; 
END 

-- Describe TEST 
CREATE TABLE "main"."test" ( 
    "id" INTEGER PRIMARY KEY AUTOINCREMENT, 
    "name" TEXT, 
    "last_update_ts" DATETIME DEFAULT CURRENT_TIMESTAMP 
); 
Các vấn đề liên quan