web-dev-qa-db-ja.com

SQLiteを使用したcurrent_timestampの更新時

行が更新されるたびに、現在のタイムスタンプでフィールドを更新したい。

MySQLでは、テーブルを宣言するときに行います

LastUpdate TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP

ただし、「更新時」の部分はSQLiteでは機能しません。自動的に実行する方法が見つかりませんでした。トリガーを宣言する必要がありますか?

[〜#〜] edit [〜#〜]:レコードの場合、ここに私の現在のトリガーがあります:

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

ありがとう

26
Jonas

はい、トリガーを使用する必要があります。 (チェックするだけです:投稿されたトリガーは正しく機能していますか?一見すると、私にはそれで問題ありません。)

MySQLの_ON UPDATE CURRENT_TIMESTAMP_は、かなりユニークな単一目的のショートカットです。それが現実さ;この構成は、他の値やTIMESTAMP以外の列タイプに対して同様に使用することはできません。 (この機能が _CREATE TABLE_ page の代わりに TIMESTAMP type page でどのように定義されているかに注意してください、この機能はTIMESTAMP列に固有であり、一般に_CREATE TABLE_ステートメントに固有ではありません。)TIMESTAMPタイプに固有ですが、 SQLiteには、明確な日付/時刻型もありません

私の知る限り、実際のトリガーを使用する代わりにこのショートカットを提供するRDBMSは他にありません。私が読んだことから、MS SQL、SQLite、PostgreSQL、およびOracleでこれを実行するには、トリガーを使用する必要があります。


通行人のための最後のメモ:

これは、外部キー制約に関して_ON UPDATE_句と混同しないでください。これはまったく異なるもので、外部キー制約をサポートするすべてのRDBMS(MySQLとSQLiteの両方を含む)が持っている可能性があります。

22
Wiseguy

JohnはデフォルトのSQLite設定については正しく、このトリガーは無限ループを引き起こします。再帰を回避するには、WHEN句を使用します。

recursive_triggers設定はオンです:

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;
3
aMarCruz
-- 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  
);  
0
Jixster

それを行うには、より効率的で見栄えの良い方法があります。たとえば、次のようになります。

-- List all required fields after 'OF' except the LastUpdate field to prevent infinite loop
CREATE TRIGGER UpdateLastTime UPDATE OF field1, field2, fieldN ON Package
BEGIN
  UPDATE Package SET LastUpdate=CURRENT_TIMESTAMP WHERE ActionId=ActionId;
END;

このようなコードは私のプロジェクトでテストされています。詳細なSQLiteトリガーの説明はここにあります https://www.sqlite.org/lang_createtrigger.html

0
Dmitrij

私が作っているアプリのためにこれをSQLite 3.13.0で使用してください:

CREATE TABLE IF NOT EXISTS rates(
   date TEXT,
   fromCode TEXT,
   rate TEXT,
   toCode TEXT,
   timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, 
   PRIMARY KEY(fromCode,toCode)
);
0
tanghus