매우 멍청한 질문. 어떤 사용자가 업데이트를 삽입하고 최근에 레코드를 삭제할 때 실제로 데이터베이스를 추적하려고합니다.asp.net에 의한 SQL 트리거에 매개 변수 전달
나는 데이터베이스 변경 사항을 추적하기 위해 트리거를 만들었습니다. 여기
는내 코딩
USE [test]
GO
/****** Object: Trigger [dbo].[tr_trigtest1] Script Date: 09/05/2012 16:31:18 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tr_trigtest1] ON [dbo].[test1] 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 = @UserName ,
@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
모든 것은, 내가 어떤 기록이 갱신 될 때, 그 세부 사항을 얻을 삽입하고 삭제합니다 부드러운 내 SQL 트리거입니다
public partial class WebForm1 : System.Web.UI.Page
{
private testEntities entity = new testEntities();
protected void Page_Load(object sender, EventArgs e)
{
trigtest test = trigtest.Createtrigtest(10, 12);
entity.AddTotrigtests(test);
entity.SaveChanges();
}
}
이제 문제가 생겼습니다. 백엔드 코드로 @username에 값을 전달할 수 있습니까? 트리거를 수정하는 방법은? 죄송 합니다만 여전히 SQL 트리거에 대해 매우 신선합니다. 나는 사용자 이름은 사용자의 EF 연결 문자열에 따라 실제로 반환하는 어떤 가치 기능 SUser_SName()
SELECT @UserName = SUser_SName();
에 의해 반환 그것을
동적 SQL을 구축하면 트리거가 테이블에서 쓰기 작업을 매우 느리게 만듭니다. 정적 트리거를 동적으로 생성하기 위해 DDL을 사용하지 않는 이유는 무엇입니까? – StuartLC
안녕하세요, 몇 가지 예를 길드 수 있습니까? 나는 여전히 매우 새로운 SQL 트리거 – user998405