SQL Server 2012データベース用の新しいdbスキーマを設計しています。
各テーブルには、modified
およびcreated
という2つの追加の列が必要です。これらの列は、行が挿入または更新されるとすぐに自動的に変更されます。
どうやってそこにたどり着くのがベストかわからない。
トリガーはそれを処理するための最良の方法だと思います。
私はトリガーを使用して例を見つけようとしていました。
私はそれが非常に一般的なシナリオであると想定しましたが、まだ答えが見つかりませんでした。
created
列は単純です-新しい行が挿入されたときに設定されるデフォルトの制約を持つDATETIME2(3)
列だけです:
Created DATETIME2(3)
CONSTRAINT DF_YourTable_Created DEFAULT (SYSDATETIME())
したがって、YourTable
に行を挿入し、Created
の値を指定しない場合、現在の日付と時刻に設定されます。
modified
は、AFTER UPDATE
ケースのトリガーを作成して更新する必要があるため、もう少し作業が必要です。これをSQL Serverに宣言することはできません。
Modified DATETIME2(3)
その後
CREATE TRIGGER updateModified
ON dbo.YourTable
AFTER UPDATE
AS
UPDATE dbo.YourTable
SET modified = SYSDATETIME()
FROM Inserted i
WHERE dbo.YourTable.PrimaryKey = i.PrimaryKey
そのテーブルの主キーのベーステーブルで更新されたすべての行を含むInserted
擬似テーブルを結合する必要があります。
そして、modified
列を持ちたい各テーブルに対して、このAFTER UPDATE
トリガーを作成する必要があります。
通常、次の列を使用できます。
LastModifiedBy
とCreatedBy
はusers
テーブル(UserID
)への参照であり、LastModifiedOn
とCreatetOn
列は日付と時刻の列。
次のオプションがあります。
トリガーを使用しないソリューション-「トリガーを作成する最良の方法は、トリガーを作成しないことです。」と読んでいますが、一般的にそれらが痛いことを知っている必要がありますパフォーマンス。そのため、それらを回避できる場合は、回避する方が良い場合があります。トリガーを使用することでさえ、場合によっては最も簡単なことのように見えるかもしれません。
したがって、すべてのINSERT
およびUPDATE
ステートメントを編集して、現在のUserID
および現在の日時を含めるだけです。そのようなuser ID
を定義できない場合(匿名ユーザー)、代わりに0
を使用でき、列のデフォルト値(user ID
が指定されていない場合はNULL
になります)。 NULL
値が挿入されているのを見ると、「有罪」ステートメントを見つけて編集する必要があります。
トリガーを使用したソリューション-AFTER INSERT, UPDATE
トリガーを作成し、そこにユーザー列を追加できます。トリガーのコンテキストで現在の日付と時刻を取得するのは簡単です(たとえば、GETUTCDATE()
を使用します)。ここでの問題は、トリガーがパラメーターの受け渡しを許可しないことです。したがって、user ID
値を挿入しておらず、トリガーに渡すことができないためです。現在のユーザーを見つける方法は?
SET CONTEXT_INFO および CONTEXT_INFO を使用できます。すべてのinsert
およびupdate
ステートメントの前に、SET CONTEXT_INFO
を使用してcurrent user ID
を現在のコンテキストに追加し、トリガーでCONTEXT_INFO
関数を使用して抽出する必要があります。
そのため、トリガーを使用する場合は、すべてのINSERT
節とUPDATE
節を再度編集する必要があります。そのため、これらを使用しない方がよいのです。
とにかく、日付と時刻の列のみが必要で、列によって作成/変更する必要がない場合、現在および将来、他のステートメントを編集しないため、トリガーの使用はより耐久性があり、簡単です。
SQL Server 2016
を使用して、セッションの詳細を読み取るために SESSION_CONTEXT 関数を使用できるようになりました。詳細は sp_set_session_context (read-only
またはread and write
として)を使用して設定されます。物事は少しユーザーフレンドリーです:
EXEC sp_set_session_context 'user_id', 4;
SELECT SESSION_CONTEXT(N'user_id');
すてきな 例 。
注意、上記では正常に動作しますが、すべての場合でなく、私は多くの時間を失い、これが役立つことがわかりました:
create TRIGGER yourtable_update_insert
ON yourtable
AFTER UPDATE
as
begin
set nocount on;
update yourtable set modified=getdate(), modifiedby = suser_sname()
from yourtable t
inner join inserted i on t.uniqueid=i.uniqueid
end
go
set nocount on;
が必要です。それ以外の場合、エラーが発生します。
Microsoft SQL Server Management Studio
行は更新されませんでした。
行5のデータはコミットされませんでした。エラーソース:Microsoft.SqlServer.Management.DataTools。エラーメッセージ:更新または削除された行の値は、行を一意にしないか、複数の行(2行)を変更します。
エラーを修正して再試行するか、ESCを押して変更をキャンセルします。
OKヘルプ
CREATE TRIGGER [dbo].[updateModified]
ON [dbo].[Transaction_details]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.Transaction_details
SET ModifedDate = GETDATE() FROM dbo.Transaction_details t JOIN inserted i ON
t.TransactionID = i.TransactionID--SYSDATETIME()
END