Может ли триггер в SQL Server записывать данные в таблицы в отдельной базе данных на отдельном сервере?

#sql-server-2008 #triggers

#sql-server-2008 #триггеры

Вопрос:

Я хочу разработать систему аудита для своей базы данных, которая записывает данные аудита в базу данных на отдельном сервере в целях безопасности. Серверы находятся в одном домене, и были созданы надлежащие разрешения учетной записи. Они оба являются серверами Windows Server 2008 R2, на которых работает SQL Server 2008 R2. Вот текущий триггер, который отлично работает, когда таблицы аудита находятся в той же базе данных, что и основная система (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
  

Все операторы SELECT ссылаются на базу данных DMCS на основном сервере (где расположены триггеры для каждой проверяемой таблицы), и все команды INSERT должны записываться в отдельную базу данных на отдельном сервере. Как мне сделать это в триггере без создания хранимой процедуры?

Ответ №1:

Да для обоих.

Вы бы изменили использование имен объектов из 3 или 4 частей

  • OtherDB.dbo.OtherTable
  • LinkedServer.RemoteDB.dbo.Table

Лично я бы использовал service broker из триггера для отправки данных на другой сервер. Я не хочу, чтобы запись завершалась неудачно из-за связанного сервера.

Или просто регистрироваться локально и отправлять на центральный сервер аудита позже с помощью служб SSIS taks или тому подобное

Ответ №2:

Вам нужно создать связанный сервер, если БД находится на другом сервере, а затем вы можете использовать нотацию из 4 частей