我面临的情况是我需要从审计日志表中获取数据并显示旧值和新值。
例如。下面是人员的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
答案 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
编辑:在查询结尾处排除错误代码