镜像表修改

时间:2008-10-28 13:02:04

标签: sql sql-server database sql-server-2005 database-design

我有一组用于跟踪账单的表。这些表是从每周运行的SSIS进程加载的。

我正在创建第二组表来跟踪对通过网络进行的账单的调整。我们的一些客户手持账单,所有这些条目都需要更加定期备份(SSIS馈送的数据总是可以再次导入,因此不会备份)。

这种行为是否有最佳做法?我正在寻找实现一个DDL触发器,它将解析ALTER TABLE调用并更改被调用的表。这有点痛苦,我很好奇是否有更好的方法。

2 个答案:

答案 0 :(得分:1)

我个人将SSIS-fed表放在一个数据库中(设置为简单恢复模式),将其他表放在同一服务器上设置为完全恢复模式的单独数据库中。然后我会定期在第二个数据库上设置备份。典型的备份计划是每周一次完整备份,每晚不同,每15-30分钟进行一次事务备份,具体取决于输入的数据量。)确保定期测试恢复备份,了解如何在客户端进行备份时尖叫因为数据库已经失效了,不是好事。

答案 1 :(得分:0)

我最终使用DDL触发器将更改的副本从一个表复制到另一个表。唯一的问题是,如果表或列名称包含保留字的一部分 - ARCH for VARCHAR - 它将导致修改脚本出现问题。

再次感谢Brent Ozar在我blogged them之前检错我的想法。

-- 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