将最新记录与审核日志表中更新列的先前记录进行比较

时间:2017-07-09 09:47:34

标签: sql-server pivot unpivot

我面临的情况是我需要从审计日志表中获取数据并显示旧值和新值。

例如。下面是人员的audit_Log

AUDIT_ID       PERSON_ID       OPERATION       NAME       ADDRESS       AGE     DOY 
    1           101             I           Prashant        Andheri     21      1991 
    2           101             U           Prashant1       Santacruz   22      1990 
    3           101             U           rashant2        Parle       23      1989

我想要所有列的最新值和先前值,如下所示

PERSON_ID       COLUMNS      OLD_VALUE       NEW_VALUE 
101             OPERATION       U               U 
101             NAME            PRASHANT1       PRASHANT2 
101             ADDRESS         Santacruz       Parle 
101             AGE             22              23 
101             BIRTH_YEAR      1990            1989 

任何人都可以帮我从上表中得到这个结果。

谢谢, PRASHANT

2 个答案:

答案 0 :(得分:0)

我试图找到一个函数/查询来做你想做的事,但我什么都没发现。所以我开发了一个程序验证工作。

CREATE PROCEDURE _spManageAuditLog 
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT AUDIT_ID, PERSON_ID, OPERATION, NAME, [ADDRESS], AGE, DOY, count(1)
    FROM dbo.audit_Log  
    GROUP BY AUDIT_ID, PERSON_ID, OPERATION, NAME, [ADDRESS], AGE, DOY;


CREATE TABLE #row (personId Int, operation char(1), name nvarchar(250),[address] nvarchar(250), age smallint,
doy smallint);


CREATE TABLE #out (PersonID Int, [columnName] nvarchar(250), OLD_VALUE nvarchar(250),NEW_VALUE  nvarchar(250));

--cursor variable
DECLARE
@AUDIT_ID   int,
@PERSON_ID  int,
@OPERATION  char,
@NAME   nvarchar,
@ADDRESS    nvarchar,
@AGE    smallint,
@DOY    smallint;


DECLARE myCursor CURSOR FOR 
    SELECT AUDIT_ID, PERSON_ID, OPERATION, NAME, [ADDRESS], AGE, DOY
    FROM dbo.audit_Log  

OPEN myCursor
FETCH NEXT FROM myCursor INTO @AUDIT_ID, @PERSON_ID, @OPERATION, @NAME, @ADDRESS, @AGE, @DOY

WHILE @@FETCH_STATUS = 0
BEGIN
    declare @countTempData int;
    select @countTempData= count(1) from #row;

    IF @countTempData=0 
     BEGIN
        Insert into #row VALUES(@PERSON_ID, @OPERATION, @NAME, @ADDRESS, @AGE, @DOY);
        --to debug
        --SELECT * FROM #row;
     END 
    ELSE
     BEGIN
        --do comparison previus row


        INSERT INTO #out VALUES (@PERSON_ID, 'Operation', (SELECT TOP(1) OPERATION FROM #row) , @OPERATION );
        INSERT INTO #out VALUES (@PERSON_ID, 'Name',(SELECT TOP(1) NAME FROM #row), @NAME );
        INSERT INTO #out VALUES (@PERSON_ID, 'Address',(SELECT TOP(1) ADDRESS FROM #row), @ADDRESS );
        INSERT INTO #out VALUES (@PERSON_ID, 'Age',(SELECT TOP(1) AGE FROM #row), @AGE );
        INSERT INTO #out VALUES (@PERSON_ID, 'BirthYear',(SELECT TOP(1) DOY FROM #row), @DOY );


        --new item became temp item
        TRUNCATE TABLE #row
        INSERT INTO #row VALUES(@PERSON_ID, @OPERATION, @NAME, @ADDRESS, @AGE, @DOY);
        --to debug
        --SELECT * FROM #row;

     END

    -- Get the next.
    FETCH NEXT FROM myCursor INTO @AUDIT_ID, @PERSON_ID, @OPERATION, @NAME, @ADDRESS, @AGE, @DOY
END 
CLOSE myCursor;
DEALLOCATE myCursor;

SELECT * FROM #out;


END
GO  

答案 1 :(得分:0)

SELECT PERSON_ID, [COLUMNS], OLD_VALUE, NEW_VALUE
FROM(
    SELECT TOP 2 PERSON_ID, ( CASE ( ROW_NUMBER() OVER( ORDER BY AUDIT_ID DESC )) WHEN 1 THEN 'NEW_VALUE' ELSE 'OLD_VALUE' END ) AS [Version],
        CAST( OPERATION AS VARCHAR( 100 )) AS OPERATION, CAST( NAME AS VARCHAR( 100 )) AS NAME,
        CAST( ADDRESS AS VARCHAR( 100 )) AS ADDRESS, CAST( AGE AS VARCHAR( 100 )) AS AGE, CAST( DOY AS VARCHAR( 100 )) AS DOY
    FROM audit_Log
    WHERE PERSON_ID = 101
    ORDER BY AUDIT_ID DESC ) AS SourceData
UNPIVOT(
    COL_VALUE FOR [COLUMNS] IN( NAME, ADDRESS, OPERATION, AGE, DOY )
    ) AS UnpivotColumns
PIVOT(
    MIN( COL_VALUE ) FOR [Version] IN( [NEW_VALUE], [OLD_VALUE] )
    ) AS PivotOldNew

注意:

  • 您需要将所有审核列值转换为通用类型。一世 选择VARCHAR( 100 )但您可能需要选择其他内容。
  • 当只有一条审核记录存在时,此代码也有效。在这种情况下 将为NULL
  • 显示OLD_VALUES

参考文献:

http://mangalpardeshi.blogspot.com.au/2009/04/unpivot-multiple-columns.html https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot

编辑:在查询结尾处排除错误代码