タイトルを書いても、これを試してみたアイデアに夢中です(しかし、ちょっと、その過程で何かを学びました)。
開発者がデータベースで移行スクリプトを実行し、その過程でデータベースに既に存在するストアドプロシージャを上書きするという問題があります(DEV、thank a deity )。
ただし、次の理由により、これらの変更を誰が行ったかを知る方法はありません。
dbo
として接続しているため、SQL Serverはprincipal_id
システムビューのsys.objects
列に値を入力しません( 詳細はこちら )。だから、私はsys.objectsにトリガーを書いてみましたが、エラーが発生したため、うまくいきませんでした(なぜ私が予期していたのかわかりません)。
オブジェクト「DEV_DB.sys.objects」は存在しないか、この操作には無効です。
また、開発者ごとにユーザーを作成して、自動移行を行ったときにユーザーが使用するようにしました。うまくいけば、その開発者がsys.objects
に行ったすべての変更は、ユーザーとしてログに記録されます。でログインしました。
ただし、principal_id
がまだ入力されていないため、これも機能しませんでした(私が行ったのは、各開発者とDBに新しいログイン/ユーザーを作成し、ログインを与えることでした- 特定のサーバーの役割 :public
、db_datawriter
、db_datareader
、db_ddladmin
)。
他に何を試すことができるかについての提案はありますか?
デフォルトのトレースをいつでもタップして、ストアドプロシージャを含むオブジェクトへの変更をキャッチできます。
次のスクリプトを試してみてください。誰が何をいつ変更したかを見つけるのは簡単です。それは私が複数のずるい開発者を見つけるのを助けました;)
SELECT t.DatabaseName, t.ObjectID,t.NTUserName,t.HostName,t.StartTime, te.name
FROM ::fn_trace_gettable('C:\Program Files\Microsoft SQL
Server\MSSQL13.SQL2016\MSSQL\Log\log.trc', DEFAULT) t
JOIN sys.trace_events te on t.EventClass = te.trace_event_id
ORDER BY t.StartTime DESC;
SQLトレースファイルが実行されている場所を見つけるには、SQLトレースファイルがどこにあるかにパスを変更する必要があります。
select path
from sys.traces
where id = 1
ヒント:ファイル名から_number
を削除して、使用可能なすべてのトレースファイルを読み取ります。ファイル名がlog_16.trc
の場合は、log.trc
に変更します。
開発者が個別にログインしている場合は、DDLトリガーを検討してください。 CREATE_PROCEDURE
、ALTER_PROCEDURE
、DROP_PROCEDURE
イベントの例を以下に示します。
USE YourDatabase;
GO
CREATE TRIGGER trgStoredProcDDL
ON DATABASE
FOR CREATE_PROCEDURE, ALTER_PROCEDURE, DROP_PROCEDURE
AS
BEGIN
--Get relevant info from EVENTDATA()
DECLARE @Login SYSNAME= EVENTDATA().value('(/EVENT_INSTANCE/LoginName)[1]', 'SYSNAME');
DECLARE @DBUser SYSNAME = EVENTDATA().value('(/EVENT_INSTANCE/UserName)[1]', 'SYSNAME');
DECLARE @Schema SYSNAME = EVENTDATA().value('(/EVENT_INSTANCE/SchemaName)[1]', 'SYSNAME');
DECLARE @Proc SYSNAME = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]', 'SYSNAME');
--Optional: error message for end user.
RAISERROR ('Please stop!', 16, 1);
--Optional: Rollback transaction that fired the DDL trigger
ROLLBACK;
--Optional: log some data to a table.
BEGIN TRAN
INSERT INTO guest.LogTable(LogMsg, LogDate, [Login], [User])
VALUES('Stored Proc was created/altered/dropped: [' + @Schema + '].[' + @Proc+ ']',
CURRENT_TIMESTAMP,
@Login,
@DBUser);
COMMIT
--Optional: send an email/alert.
DECLARE @Subj NVARCHAR(255)
SET @Subj = @@SERVERNAME + ' - Stored Proc created/altered/dropped'
EXEC msdb..sp_send_dbmail
@recipients = '[email protected]',
@subject = @Subj,
@body = 'Your message...'
END;
DDLトリガーを使用したイベントの処理に関するブログ投稿をいくつか説明します。 SQL Serverイベント処理:DDLイベント