如何在MVC4应用程序上返回指定用户的所有事务,例如,如果我想知道哪个用户删除或更新数据库中的指定记录
答案 0 :(得分:0)
您好需要维护正在执行交易的表的审计跟踪。
以下是文章链接: - Link to Complete Article
创建一个简单的SQL Server触发器来构建审计跟踪
- 设置表格
- 首先,我们创建审计表。
- 只需要在数据库中使用其中一个
IF NOT EXISTS
(SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[dbo].[Audit]’)
AND OBJECTPROPERTY(id, N’IsUserTable’) = 1)
CREATE TABLE Audit
(Type CHAR(1),
TableName VARCHAR(128),
PK VARCHAR(1000),
FieldName VARCHAR(128),
OldValue VARCHAR(1000),
NewValue VARCHAR(1000),
UpdateDate datetime,
UserName VARCHAR(128))
GO
— now we will illustrate the use of this tool — by creating a dummy test table called TrigTest.
IF EXISTS
(SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[dbo].[trigtest]’)
AND OBJECTPROPERTY(id, N’IsUserTable’) = 1)
DROP TABLE [dbo].[trigtest]
GO
CREATE TABLE trigtest
(i INT NOT NULL,
j INT NOT NULL,
s VARCHAR(10),
t VARCHAR(10))
GO
–note that for this system to work there must be a primary key
–to the table but then a table without a primary key
–isn’t really a table is it?
ALTER TABLE trigtest ADD CONSTRAINT pk PRIMARY KEY (i, j)
GO
- 现在创建触发器本身。必须为每个人创建 -table你想要监控
CREATE TRIGGER tr_trigtest ON trigtest 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)
–You will need to change @TableName to match the table to be audited
SELECT @TableName = ‘trigtest’
— date and user
SELECT @UserName = SYSTEM_USER ,
@UpdateDate = CONVERT(VARCHAR(8), GETDATE(), 112)
+ ‘ ‘ + CONVERT(VARCHAR(12), GETDATE(), 114)
— Action
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
— Get primary key select for insert
SELECT @PKSelect = COALESCE(@PKSelect+’+’,”)
+ ”'<‘ + COLUMN_NAME
+ ‘=”+convert(varchar(100),
coalesce(i.’ + COLUMN_NAME +’,d.’ + 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 Audit ( Type,
TableName,
PK,
FieldName,
OldValue,
NewValue,
UpdateDate,
UserName)
select ”’ + @Type + ”’,”’
+ @TableName + ”’,’ + @PKSelect
+ ‘,”’ + @fieldname + ””
+ ‘,convert(varchar(1000),d.’ + @fieldname + ‘)’
+ ‘,convert(varchar(1000),i.’ + @fieldname + ‘)’
+ ‘,”’ + @UpdateDate + ””
+ ‘,”’ + @UserName + ””
+ ‘ from #ins i full outer join #del d’
+ @PKCols
+ ‘ where i.’ + @fieldname + ‘ <> d.’ + @fieldname
+ ‘ or (i.’ + @fieldname + ‘ is null and d.’
+ @fieldname
+ ‘ is not null)’
+ ‘ or (i.’ + @fieldname + ‘ is not null and d.’
+ @fieldname
+ ‘ is null)’
EXEC (@sql)
END
END
GO
- 现在我们可以测试触发器了
INSERT trigtest SELECT 1,1,’hi’, ‘bye’
INSERT trigtest SELECT 2,2,’hi’, ‘bye’
INSERT trigtest SELECT 3,3,’hi’, ‘bye’
SELECT * FROM Audit
SELECT * FROM trigtest
UPDATE trigtest SET s = ‘hibye’ WHERE i <> 1
UPDATE trigtest SET s = ‘bye’ WHERE i = 1
UPDATE trigtest SET s = ‘bye’ WHERE i = 1
UPDATE trigtest SET t = ‘hi’ WHERE i = 1
SELECT * FROM Audit
SELECT * FROM trigtest
DELETE trigtest
SELECT * FROM Audit
SELECT * FROM trigtest
GO
DROP TABLE Audit
GO
DROP TABLE trigtest
GO