SQL Server 2005 の自動更新された DateTime 列 - LastUpdated
-
09-06-2019 - |
質問
テーブルを定義しました (以下のコード スニペットを参照)。行が変更されるたびに LastUpdate 列が自動的に更新されるように制約などを追加するにはどうすればよいですか?
CREATE TABLE dbo.Profiles
(
UserName varchar(100) NOT NULL,
LastUpdate datetime NOT NULL CONSTRAINT DF_Profiles_LastUpdate DEFAULT (getdate()),
FullName varchar(50) NOT NULL,
Birthdate smalldatetime NULL,
PageSize int NOT NULL CONSTRAINT DF_Profiles_PageSize DEFAULT ((10)),
CONSTRAINT PK_Profiles PRIMARY KEY CLUSTERED (UserName ASC),
CONSTRAINT FK_Profils_Users FOREIGN KEY (UserName) REFERENCES dbo.Users (UserName) ON UPDATE CASCADE ON DELETE CASCADE
)
解決
デフォルトの制約は挿入に対してのみ機能します。更新にはトリガーを使用します。
他のヒント
私も他の意見に同意します。LastUpdate 列に GetDate() のデフォルト値を設定し、トリガーを使用して更新を処理します。
次のような単純なものです。
CREATE TRIGGER KeepUpdated on Profiles
FOR UPDATE, INSERT AS
UPDATE dbo.Profiles
SET LastUpdate = GetDate()
WHERE Username IN (SELECT Username FROM inserted)
さらに凝ったことをしたい場合は、変更内容とデータベース内の内容を評価させ、違いがあった場合にのみ LastUpdate を変更します。
このことを考慮...
午前7時 - ユーザー「jsmith」は姓「Smithe」で作成されます (おっと)、LastUpdate のデフォルトは午前 7 時です
午前8時 - 「jsmith」は IT 部門に自分の名前が間違っていると電子メールで伝えました。すぐに更新を実行すると、姓は「Smith」になり、(トリガーのおかげで) LastUpdate には午前 8 時が表示されます。
午後2時 - あなたの怠け者の同僚は、ついに StumbleUpon に飽きて、メールをチェックします。彼は、名前の変更に関する「jsmith」からの以前のメッセージを確認しました。彼は走ります: プロファイルを更新 SET LastName='Smith' WHERE Username='jsmith' そして、MySpaceのサーフィンに戻ります。ただし、トリガーは姓がすでに「Smith」であることを気にしないため、LastUpdate には午後 2 時が表示されます。
update ステートメントが実行されるたびに LastUpdate を盲目的に変更する場合は、更新が行われたため技術的には正しいですが、実際に変更を比較し、それに応じて動作する方がおそらく合理的です。そうすれば、同僚による午後 2 時の Update ステートメントは引き続き実行されますが、LastUpdate には午前 8 時が表示されます。
--ケビン
私はトリガーのアイデアに同意しますが、挿入にはサブクエリの代わりに結合を使用します。ただし、ユーザー名は主キーとして特に不適切な選択であることを指摘しておきます。ユーザー名は頻繁に変更されるため、その場合は関連するすべてのテーブルを変更する必要があります。ユーザー ID をキーとして使用し、ユーザー名に一意のインデックスを付ける方がはるかに優れています。ユーザー名が変更されても、他に何も変更する必要はありません。
そのためにはトリガーを使用する必要があります。
私の提案は、lastUpdate を getdate() にデフォルト設定するストアド プロシージャを作成することです。
SQL2005 以前はトリガーを見つけて編集するのが大変だったので、私はこれまでトリガーを避けるようにしてきました。特にプロジェクトに不慣れな開発者にとってはそうです。
また、それを列定義のデフォルト値として追加します。