I want to develop an auditing system for my database that writes auditing data to a database on a separate server, for security purposes. The servers are on the same domain, and proper account permissions have been created. They are both Windows Server 2008 R2 servers running SQL Server 2008 R2. Here is the current trigger that works fine when the auditing tables are in the same database as the main system (DMCS).
USE [DMCS]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[AUDIT_SAMPLE] on dbo.SAMPLE
FOR INSERT, UPDATE, DELETE
AS
DECLARE @OLD VARCHAR(MAX);
DECLARE @NEW VARCHAR(MAX);
DECLARE @RECORDID INT;
DECLARE @USERID INT;
DECLARE @ID INT;
SET @ID = ((SELECT MAX(Audit_Action_ID) AS MaxID FROM DMCS_AUDIT_ACTION) + 1);
-- Increments ID column, you could also simply set it as an identity field with auto-increment
-- IF UPDATE (Action_Type_ID = 3)
IF EXISTS (SELECT Sample_ID, Sample_Data, Sample_User_ID FROM deleted) AND EXISTS (SELECT Sample_ID, Sample_Data, Sample_User_ID FROM inserted)
BEGIN
SET @RECORDID = (SELECT Sample_ID FROM deleted);
SET @USERID = (SELECT Sample_User_ID FROM deleted);
SET @OLD = (SELECT Sample_Data FROM deleted);
SET @NEW = (SELECT Sample_Data FROM inserted);
INSERT INTO DMCS_AUDIT_ACTION VALUES (@ID, 6, 3, @USERID, @RECORDID, USER, @OLD, @NEW, GETDATE(), 'S');
END
-- IF DELETE (Action_Type_ID = 4)
IF EXISTS (SELECT Sample_ID, Sample_Data, Sample_User_ID FROM deleted) AND NOT EXISTS (SELECT Sample_ID, Sample_Data, Sample_User_ID FROM inserted)
BEGIN
SET @RECORDID = (SELECT Sample_ID FROM deleted);
SET @USERID = (SELECT Sample_User_ID FROM deleted);
SET @OLD = (SELECT Sample_Data FROM deleted);
INSERT INTO DMCS_AUDIT_ACTION VALUES (@ID, 6, 4, @USERID, @RECORDID, USER, @OLD, 'N/A', GETDATE(), 'S');
END
-- IF INSERT (Action_Type_ID = 2)
IF NOT EXISTS (SELECT Sample_ID, Sample_Data, Sample_User_ID old FROM deleted) AND EXISTS (SELECT Sample_ID, Sample_Data, Sample_User_ID new FROM inserted)
BEGIN
SET @RECORDID = (SELECT Sample_ID FROM inserted);
SET @USERID = (SELECT Sample_User_ID FROM inserted);
SET @NEW = (SELECT Sample_Data FROM inserted);
INSERT INTO DMCS_AUDIT_ACTION VALUES (@ID, 6, 2, @USERID @RECORDID, USER, 'N/A', @NEW, GETDATE(), 'S');
END
All of the SELECT statements are referencing the DMCS database on the primary server (which is where the triggers are located for each table being audited), and all the INSERT commands need to write to a separate database on a separate server. How do I do this within the trigger without creating a stored procedure?
Yes to both.
You’d change to use 3 or 4 part object names
Personally I’d use service broker from the trigger to send data to another server. I don’t want to a write to fail because of a linked server.
Or just log locally and send to central audit server later with an SSIS taks or such