Модификация зеркального стола - PullRequest
0 голосов
/ 28 октября 2008

У меня есть набор таблиц, которые используются для отслеживания счетов. Эти таблицы загружаются из процесса SSIS, который выполняется еженедельно.

Я нахожусь в процессе создания второго набора таблиц для отслеживания корректировок счетов, сделанных через Интернет. Некоторые из наших клиентов вручную вводят свои счета, и для всех этих записей необходимо выполнять резервное копирование по более регулярному графику (данные, подаваемые службами SSIS, всегда можно импортировать снова, поэтому они не сохраняются).

Есть ли лучшая практика для этого типа поведения? Я смотрю на реализацию триггера DDL, который будет анализировать вызов ALTER TABLE и изменять вызываемую таблицу. Это несколько болезненно, и мне любопытно, есть ли лучший способ.

Ответы [ 2 ]

1 голос
/ 28 октября 2008

Лично у меня в одной базе данных будут таблицы, снабженные службами SSIS (для простого режима восстановления), а другие таблицы - в отдельной базе данных на том же сервере, для которого установлен полный режим восстановления. Затем я бы регулярно создавал резервные копии на второй базе данных. Типичным расписанием резервного копирования будет полное резервное копирование один раз в неделю, разное еженедельное и резервное копирование транзакций каждые 15-30 минут в зависимости от объема вводимых данных.) Обязательно периодически проверяйте восстановление резервных копий, изучая, как это делать, когда клиент кричать, потому что база данных не работает, хорошая вещь.

0 голосов
/ 31 октября 2008

Я закончил тем, что использовал триггер DDL, чтобы сделать копию изменений из одной таблицы в другую. Единственная проблема заключается в том, что если имя таблицы или столбца содержит часть зарезервированного слова - ARCH для VARCHAR - это вызовет проблемы со сценарием модификации.

Еще раз спасибо Бренту Озару за проверку моих мыслей до того, как я опубликовал их в блоге .

-- Create pvt and pvtWeb as test tables
CREATE TABLE [dbo].[pvt](
   [VendorID] [int] NULL,
   [Emp1] [int] NULL,
   [Emp2] [int] NULL,
   [Emp3] [int] NULL,
   [Emp4] [int] NULL,
   [Emp5] [int] NULL
) ON [PRIMARY];
GO


CREATE TABLE [dbo].[pvtWeb](
   [VendorID] [int] NULL,
   [Emp1] [int] NULL,
   [Emp2] [int] NULL,
   [Emp3] [int] NULL,
   [Emp4] [int] NULL,
   [Emp5] [int] NULL
) ON [PRIMARY];
GO


IF EXISTS(SELECT * FROM sys.triggers WHERE name = ‘ddl_trigger_pvt_alter’)
   DROP TRIGGER ddl_trigger_pvt_alter ON DATABASE;
GO

-- Create a trigger that will trap ALTER TABLE events
CREATE TRIGGER ddl_trigger_pvt_alter
ON DATABASE
FOR ALTER_TABLE
AS
   DECLARE @data XML;
   DECLARE @tableName NVARCHAR(255);
   DECLARE @newTableName NVARCHAR(255);
   DECLARE @sql NVARCHAR(MAX);

   SET @sql = ”;
   -- Store the event in an XML variable
   SET @data = EVENTDATA();

   -- Get the name of the table that is being modified
   SELECT @tableName = @data.value(‘(/EVENT_INSTANCE/ObjectName)[1]‘, ‘NVARCHAR(255)’);
   -- Get the actual SQL that was executed
   SELECT @sql = @data.value(‘(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]‘, ‘NVARCHAR(MAX)’);

   -- Figure out the name of the new table
   SET @newTableName = @tableName + ‘Web’;

   -- Replace the original table name with the new table name
   -- str_replace is from Robyn Page and Phil Factor’s delighful post on 
   -- string arrays in SQL. The other posts on string functions are indispensible
   -- to handling string input
   --
   -- http://www.simple-talk.com/sql/t-sql-programming/tsql-string-array-workbench/
   -- http://www.simple-talk.com/sql/t-sql-programming/sql-string-user-function-workbench-part-1/
   --http://www.simple-talk.com/sql/t-sql-programming/sql-string-user-function-workbench-part-2/
   SET @sql = dbo.str_replace(@tableName, @newTableName, @sql);

   -- Debug the SQL if needed.
   --PRINT @sql;

   IF OBJECT_ID(@newTableName, N’U’) IS NOT NULL
   BEGIN
       BEGIN TRY
           -- Now that the table name has been changed, execute the new SQL
           EXEC sp_executesql @sql;
       END TRY
       BEGIN CATCH
           -- Rollback any existing transactions and report the full nasty 
           -- error back to the user.
           IF @@TRANCOUNT > 0
               ROLLBACK TRANSACTION;

           DECLARE
               @ERROR_SEVERITY INT,
               @ERROR_STATE    INT,
               @ERROR_NUMBER   INT,
               @ERROR_LINE     INT,
               @ERROR_MESSAGE  NVARCHAR(4000);

           SELECT
               @ERROR_SEVERITY = ERROR_SEVERITY(),
               @ERROR_STATE    = ERROR_STATE(),
               @ERROR_NUMBER   = ERROR_NUMBER(),
               @ERROR_LINE     = ERROR_LINE(),
               @ERROR_MESSAGE  = ERROR_MESSAGE();

           RAISERROR(‘Msg %d, Line %d, :%s’,
               @ERROR_SEVERITY,
               @ERROR_STATE,
               @ERROR_NUMBER,
               @ERROR_LINE,
               @ERROR_MESSAGE);
       END CATCH
   END
GO




ALTER TABLE pvt
ADD test INT NULL;
GO

EXEC sp_help pvt;
GO

ALTER TABLE pvt
DROP COLUMN test;
GO

EXEC sp_help pvt;
GO
...