行が更新されるたびに、現在のタイムスタンプでフィールドを更新したい。
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
ありがとう
はい、トリガーを使用する必要があります。 (チェックするだけです:投稿されたトリガーは正しく機能していますか?一見すると、私にはそれで問題ありません。)
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の両方を含む)が持っている可能性があります。
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;
-- 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
);
それを行うには、より効率的で見栄えの良い方法があります。たとえば、次のようになります。
-- 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
私が作っているアプリのためにこれを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)
);