审计表更新的通用存储过程

时间:2013-09-18 07:42:40

标签: sql-server tsql stored-procedures triggers

是否有通用存储过程来审核表。我实际上已经创建了一个,但我认为它的效率和存储过程都不长。如果有人知道更好的方法,请帮助我......!

这是我的表触发器。

ALTER TRIGGER [dbo].[Trigger3]
ON  [dbo].[UserInfo]
AFTER Update
AS 
BEGIN
    SET NOCOUNT ON;

    DECLARE @TABLENAME VARCHAR(50)
    DECLARE @var varbinary

    SELECT * INTO #TEMPINSERTED FROM inserted
    SELECT * INTO #TEMPDELETED FROM deleted 

    SET @var = COLUMNS_UPDATED()

    EXEC TetsProc #TEMPINSERTED, #TEMPDELETED, @@PROCID, @var

    DROP TABLE #TEMPINSERTED 
    DROP TABLE #TEMPDELETED  
END 

这是我的存储过程

ALTER PROCEDURE [dbo].[TetsProc]
( @insertTable varchar(max),
@deleteTable  varchar(max),
@IDZ varchar(max),
@var1 varbinary 
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

DECLARE @TABLE AS TABLE (COL_NAME NVARCHAR(MAX))
DECLARE @idTable INT

SELECT  @idTable = T.id 
FROM    sysobjects P JOIN sysobjects T ON P.parent_obj = T.id 
WHERE   P.id = @IDZ

declare @q1  nvarchar(max),@q2 nvarchar(max) 
set @q1 = 'select * from ' + @insertTable
set @q2 =  'select * from ' +  @deleteTable


DECLARE @TABLENAME NVARCHAR(250)


SELECT @TABLENAME = OBJECT_NAME(parent_obj)
FROM sysobjects WHERE ID = @IDZ

 ----RETURN COLUMNS IF THEY ARE UPDATED----   
 SELECT  @idTable = T.id 
 FROM    sysobjects P JOIN sysobjects T ON P.parent_obj = T.id 
 WHERE   P.id = @@procid

DECLARE @Columns_UpdateD VARCHAR(50)

SELECT  @Columns_Update = ISNULL(@Columns_Updated + ', ', '') + name 
FROM    syscolumns 
WHERE   id = @idTable   
AND  CONVERT(VARBINARY,REVERSE(@var1)) & POWER(CONVERT(BIGINT, 2), colorder - 1)  > 0

select status into #TmpcolumnsUpdated from dbo.ParseByComma(@Columns_UpdateD)


DECLARE @QRY1 NVARCHAR(MAX)
DECLARE @QRY2 NVARCHAR(MAX)
declare @column_name varchar(50)

DECLARE cursorColumnName CURSOR FOR  
select status from #TmpcolumnsUpdated
OPEN cursorColumnName   
FETCH NEXT FROM cursorColumnName INTO @column_name 

WHILE @@FETCH_STATUS = 0   
BEGIN   
   SET @QRY1= 'SELECT '+@column_name + '  FROM '+ @insertTable 
   SET @QRY2= 'SELECT '+@column_name + '  FROM ' + @deleteTable


DECLARE @tab AS TABLE (OLD_COL VARCHAR(10)) 
DECLARE @tab1 AS TABLE (NEW_COL VARCHAR(10)) 


INSERT into @tab EXECUTE  sp_executesql @QRY2
INSERT into @tab1 EXECUTE  sp_executesql @QRY1



DECLARE @OLD_VALUE VARCHAR(MAX)=(SELECT OLD_COL FROM @tab)
DECLARE @NEW_VALUE VARCHAR(MAX)=(SELECT NEW_COL FROM @tab1)

IF(@OLD_VALUE!=@NEW_VALUE)
BEGIN
  INSERT INTO UpdateInfo (Table_Name,Col_Name,Old_Value,New_Value,Time)
  (
   SELECT
   @TABLENAME,
   @column_name,
   @OLD_VALUE,
   @NEW_VALUE,
   GETDATE()
  )
  SELECT * FROM UpdateInfo 
  END

DELETE FROM @tab
DELETE FROM @tab1


FETCH NEXT FROM cursorColumnName INTO @column_name
END   

CLOSE cursorColumnName   
DEALLOCATE cursorColumnName

drop table #TmpcolumnsUpdated

END

1 个答案:

答案 0 :(得分:0)

看起来是一种可靠的方法来降低服务器的性能。

如果您使用的是SQL Server 2012,我建议您查看Sql Server Audit

如果你必须坚持你的机制,至少会丢失PROC中的光标。