Below is a table audit setup. Without changing any table or field names and rather customized by me from the basic original, but I hope you'll get the idea; in MSSQL
create the audit table ============================================== /****** Object: Table [dbo].[ALLCONTACTSHISTORY] Script Date: 04/07/2008 19:19:59 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[ALLCONTACTSHISTORY]( [AUDITREF] [int] IDENTITY(1,1) NOT NULL, [AUDITTYPE] [char](1) NOT NULL, [COLUMN_NAME] [varchar](128) NOT NULL, [USERREF] [int] NOT NULL, [OLDVALUE] [varchar](8000) NULL, [NEWVALUE] [varchar](8000) NULL, [UPDATED] [datetime] NOT NULL, [BYWHO] [varchar](128) NOT NULL, CONSTRAINT [PK_ALLCONTACTSHISTORY] PRIMARY KEY CLUSTERED ( [AUDITREF] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO /* ====================================== create the trigger on ALLCONTACTS which fills the audit table ====================================== */ /****** Object: Trigger [dbo].[TR_AUDIT_ALLCONTACTS] Script Date: 04/07/2008 19:09:58 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE trigger [dbo].[TR_AUDIT_ALLCONTACTS] on [dbo].[ALLCONTACTS] FOR INSERT, UPDATE, DELETE AS declare @bit int , @field int , @maxfield int , @char int , @fieldname varchar(128) , @TableName varchar(128) , @PKCols varchar(1000) , @sql varchar(2000), @UpdateDate varchar(21) , @UserName varchar(128) , @Type char(1) , @PKSelect varchar(1000), @jobref int, @doIt bit set @TableName = 'ALLCONTACTS' set @doIt = 1 -- date and user SELECT @UserName = ISNULL(BYWHO,'Unknown') FROM inserted select @UpdateDate = convert(varchar(8), getdate(), 112) + ' ' + convert(varchar(12), getdate(), 114) -- Special username 'SysAdmin' to NOT insert anything into audit table if @UserName = 'SysAdmin' set @doIt = 0 -- Action if @doit = 1 BEGIN if exists (select * from inserted) if exists (select * from deleted) select @Type = 'U' else select @Type = 'I' else select @Type = 'D' -- get list of columns select * into #ins from inserted select * into #del from deleted -- Get primary key columns for full outer join select @PKCols = coalesce(@PKCols + ' and', ' on') + ' i.' + c.COLUMN_NAME + ' = d.' + c.COLUMN_NAME from INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk , INFORMATION_SCHEMA.KEY_COLUMN_USAGE c where pk.TABLE_NAME = @TableName and CONSTRAINT_TYPE = 'PRIMARY KEY' and c.TABLE_NAME = pk.TABLE_NAME and c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME if @PKCols is null begin raiserror('no PK on table %s', 16, -1, @TableName) return end select @field = 0, @maxfield = max(ORDINAL_POSITION) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName while @field < @maxfield begin select @field = min(ORDINAL_POSITION) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName and ORDINAL_POSITION > @field select @bit = (@field - 1 )% 8 + 1 select @bit = power(2,@bit - 1) select @char = ((@field - 1) / 8) + 1 if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0 or @Type in ('I','D') begin select @fieldname = COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName and ORDINAL_POSITION = @field select @sql = 'insert ALLCONTACTSHISTORY (AUDITTYPE, USERREF,COLUMN_NAME, OLDVALUE, NEWVALUE, UPDATED, BYWHO)' select @sql = @sql + ' select ''' + @Type + '''' select @sql = @sql + ', i.USERREF' select @sql = @sql + ',''' + @fieldname + '''' select @sql = @sql + ', ISNULL(CASE WHEN len(convert(varchar(1000),d.' + @fieldname + ')) = 0 THEN ''[blank]'' WHEN ISDATE(convert(varchar(20),d.' + @fieldname + '))=1 THEN convert(varchar(17),d.' + @fieldname +', 113) ELSE convert(varchar(1000),d.' + @fieldname + ') END,''[blank]'')' select @sql = @sql + ', ISNULL(CASE WHEN len(convert(varchar(1000),i.' + @fieldname + ')) = 0 THEN ''[blank]'' WHEN ISDATE(convert(varchar(20),i.' + @fieldname + '))=1 THEN convert(varchar(17),i.' + @fieldname +', 113) ELSE convert(varchar(1000),i.' + @fieldname + ') END,''[blank]'')' select @sql = @sql + ',''' + @UpdateDate + '''' select @sql = @sql + ',''' + @UserName + '''' select @sql = @sql + ' from #ins i full outer join #del d' select @sql = @sql + @PKCols select @sql = @sql + ' where i.' + @fieldname + ' <> d.' + @fieldname select @sql = @sql + ' or (i.' + @fieldname + ' is null and d.' + @fieldname + ' is not null)' select @sql = @sql + ' or (i.' + @fieldname + ' is not null and d.' + @fieldname + ' is null)' exec (@sql) --PRINT @sql end end END go =============================================== Regards Richard > -----Original Message----- > From: Phill B [mailto:[EMAIL PROTECTED] > Sent: 07 April 2008 17:30 > To: CF-Talk > Subject: Re: Can you guys give me your thoughts on this? > > Very true. The problem I'm having is that I cant figure out > how to do this in a database. I've never worked with a > database driven application that stores revisions that I can > dig through the code to see how they do it. > Plus, I couldn't find any good articles or books on this sort > of thing. > That's why I'm asking for help. I know there has to be a > better way. I just don't have the experience to pull from to > figure out what it is. > > On Mon, Apr 7, 2008 at 11:17 AM, Dave Watts wrote: > > > > The product will be stored in the database but all the > versions of > > > it would be stored on the server in XML with the > transactions being > > > recorded in it. > > > > Why not store that in the database? That's what databases > are for. XML > > is better for transport between systems, databases are > better for storage. > > > > Dave Watts, CTO, Fig Leaf Software > > > > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Adobe® ColdFusion® 8 software 8 is the most important and dramatic release to date Get the Free Trial http://ad.doubleclick.net/clk;192386516;25150098;k Archive: http://www.houseoffusion.com/groups/CF-Talk/message.cfm/messageid:302891 Subscription: http://www.houseoffusion.com/groups/CF-Talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=11502.10531.4