2017-01-11 15 views
3

履歴テーブルにあるデータを変更したユーザー/接続に関する情報を取得できますか?私は一時的なテーブルを使用できる監査シナリオについて読んでおり、誰がデータを変更したのかを検出することが可能です。しかし、どうしたらいいですか?SQL Server 2016 - 時間表 - ユーザーを識別する方法

+1

これは監査用ではありません。それについて考えると、ユーザーが行を変更すると、基本表の行がユーザーが変更した行になります。したがって、履歴行を作成したユーザーのユーザー名を取得できなかったため、昨日更新した行を更新する可能性があり、履歴表に移動する行は昨日の変更を表しています。したがって、トリガーを使用して更新される基本表の列を作成する必要がありますが、履歴行の2つのバージョンが作成されます(前のエディターでは1つ、新しいエディターでは1つ)。 –

+0

そして、あなたはINSTEAD OFトリガーでこれを回り込むことはできません。私はそれを試みたが、抜け穴があったが、[私はそれを報告し、それを修正した](https://connect.microsoft.com/SQLServer/feedback/details/2769923/can-easily-work-around-instead-テンポラリ・オン・テンポラル・テーブル)。 –

+0

ヒントのThx。私はこのドイツ語/英語msdn記事を読む。https://msdn.microsoft.com/en-us/library/mt631669.aspx データ監査 "重要な情報を保管しておく必要のあるテーブルを一時的にシステムバージョン管理する何が変更されたのか、誰がいつ誰を***、どの時点でデータフォレンジックを実行するのかを追跡することができます。 私は現在、usercolumnとcdcのソリューションを使用しています。私はこの解決策を一時的な表に置き換えることができると思った。しかし、私は次の更新を待つ必要があるように見えます。 – user1481065

答えて

2

一時テーブルの現在の実装では、時間ベースの情報だけを記録し、変更を行ったセッションについては何も記録しません。そしてその状況が将来変わるかもしれない何らかの内部的な知識を持っている私にその声明を読まないでください。私はそれについて何も知らない。あなたがその情報を必要とするならば、それを行に記録する必要があります。これを行うための古典的なアプローチは、DML操作で発生するトリガを使用し、その値をユーザーのために維持することです。

0

この問題を解決するために私が考えていた別のオプションは、行が保存または更新されるときに満たされる基本一時テーブルにLastModifiedByフィールドを持つことです。

これにより、誰がテーブルを変更したかがわかり、履歴レコードが作成されます。前述のAaronのように、トリガーで実行できますが、挿入/更新に入る前にそれを決定し、レコードが更新された時点でLastModifiedByフィールドに値を設定することを考えています。

これは、レコードが変更されるたびに履歴テーブルにも記録されます。

+0

これは、ストアドプロシージャを介してすべてのデータアクセスを制御したり、更新を発行するアプリケーションコードにアクセスできる場合に機能します。多くはできません。 –

+2

私はLastModifiedByフィールドを使用し、新しい_SESSION_CONTEXT_機能を利用して(まだ生産準備ができていない)ソリューションを作成しました。 私は接続を開いている間に設定した値 'SESSION_CONTEXT( 'UserID')'でフィールドにデフォルトの制約を作成しました。それは正常に動作しますが、誰かが明示的に値を述べると上書きすることができます。 –

2

私のソリューションはトリガーを必要としません。メインテーブルには、ログインしたユーザーが常に含まれている計算列があります。

フィールドLoggedInUserは常に、現在すべてのレコードにユーザーログインの名前が含まれているため、任意の変更だった時に、履歴テーブルに保存されるなど

CREATE TABLE dbo.Employees(
    EmployeeID INT NOT NULL, 
    FirstName sysname NOT NULL, 
    ValidFrom DATETIME2(7) GENERATED ALWAYS AS ROW START NOT NULL, 
    ValidTo DATETIME2(7) GENERATED ALWAYS AS ROW END NOT NULL, 
    LoggedInUser AS (SUSER_SNAME()), --<<-- computed column 

...任意のレコードにを作成しました。

もちろん、メインテーブルではそれほど有用ではありません。誰が各レコードを最後に変更したかはわかりません。 しかし、履歴テーブルでは、変更が行われた時点でフリーズします。これは非常に便利です(ただし、開始時刻ではなく、期間の最後に記録します)。

計算された列としてLoggedInUserはNULL可能でなければならないことに注意してください。したがって、履歴テーブルの対応する列も同じでなければなりません。

メイン(現在の)テーブル: Main table

履歴テーブル:もちろん History table

履歴テーブルで、それは、その状態から記録を変え者ではない記録しますにその状態、つまり有効期間の終了時にログインしたユーザーに送信します。削除にも機能しますが、SQL Serverの一時テーブルシステムでは、挿入の履歴テーブルにレコードが挿入されません。

これを改善する方法についてのご意見は、歓迎します。履歴表の各有効期間の開始で変更を行った人を記録する方法。メインテーブルに別の計算フィールドが含まれているという考えがあります。これは、UDFを使用して履歴テーブルの最後の変更を行ったユーザーを取得します。

編集:トリガーを使用する@Aaron Bertrandの優れた記事hereから多くのインスピレーションを見つけました。

+0

あなたのソリューションを共有するためのThx、それは私のために非常に便利でした。 – user1481065

関連する問題