审计 SQL Server - 谁在改变什么,什么时候改变? SOX 投诉

问题描述

在我的组织中,我们所做的日志记录或任​​何形式的记录都非常有限,以捕捉谁在何时更改什么内容

在这里寻求帮助,以了解捕获 sql Server 数据库中发生的任何日志记录的最佳实践。

我正在考虑根据用户可以使用应用程序执行的重要业务用例来查看表格,然后制作一个包含以下字段的 xl 文件,以便我保留该文件作为我自己的参考。

>

current XL file to start to capture initial changes

我的问题:是否有其他更好的方法来捕获数据库中的当前更改,我是否可以在 sql Server 中使用一种方法来确定我们是否正在捕获数据库中的任何日志记录?

我们没有任何 CDC 实施或 C2 审计跟踪启用或更改跟踪启用。

管理层希望利用数据库表中捕获的数据。

解决方法

我正在做一个类似的项目,你可以使用下面的设计,我正在用学生学科示例进行解释

CREATE TABLE [dbo].[AudRel](
    [AudId] [int] IDENTITY(1,1) NOT NULL,[AudTableName] [varchar](100) NULL,[AudFieldName] [varchar](100) NULL,[AudFieldID] [varchar](30) NULL,CONSTRAINT [PK_AuditRel] PRIMARY KEY CLUSTERED 
(
    [AudId] ASC
)WITH (PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[Student](
    [StudentID] [int] IDENTITY(1,[StudentName] [varchar](100) NULL,CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED 
(
    [StudentID] ASC
)WITH (PAD_INDEX = OFF,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


CREATE TABLE [dbo].[Student_Audit](
    [ID] [int] IDENTITY(1,[StudentID] [int] NOT NULL,[StudentName] [varchar](100) NULL
) ON [PRIMARY]

CREATE TABLE [dbo].[StudentSubject](
    [SSID] [int] IDENTITY(1,[StudentID] [int] NULL,[SubjectID] [int] NULL,CONSTRAINT [PK_StudentSubject] PRIMARY KEY CLUSTERED 
(
    [SSID] ASC
)WITH (PAD_INDEX = OFF,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[StudentSubject_Audit](
    [ID] [int] IDENTITY(1,[SSID] [int] NOT NULL,[SubjectID] [int] NULL
) ON [PRIMARY]

CREATE TABLE [dbo].[Subject](
    [SubjectID] [int] IDENTITY(1,[SubjectName] [varchar](50) NULL,CONSTRAINT [PK_Subject] PRIMARY KEY CLUSTERED 
(
    [SubjectID] ASC
)WITH (PAD_INDEX = OFF,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[Subject_Audit](
    [ID] [int] IDENTITY(1,[SubjectID] [int] NOT NULL,[SubjectName] [varchar](50) NULL
) ON [PRIMARY]


SET IDENTITY_INSERT [dbo].[AudRel] ON 
INSERT [dbo].[AudRel] ([AudId],[AudTableName],[AudFieldName],[AudFieldID]) VALUES (1,N'Student',N'StudentName',N'StudentID')
INSERT [dbo].[AudRel] ([AudId],[AudFieldID]) VALUES (2,N'Subject',N'SubjectName',N'SubjectID')


SET IDENTITY_INSERT [dbo].[AudRel] OFF

SET IDENTITY_INSERT [dbo].[Student] ON 
INSERT [dbo].[Student] ([StudentID],[StudentName]) VALUES (1,N'Alex')
INSERT [dbo].[Student] ([StudentID],[StudentName]) VALUES (2,N'DSouza')
SET IDENTITY_INSERT [dbo].[Student] OFF

SET IDENTITY_INSERT [dbo].[StudentSubject] ON 
INSERT [dbo].[StudentSubject] ([SSID],[StudentID],[SubjectID]) VALUES (1,1,1)
INSERT [dbo].[StudentSubject] ([SSID],[SubjectID]) VALUES (2,2,[SubjectID]) VALUES (3,2)
SET IDENTITY_INSERT [dbo].[StudentSubject] OFF

SET IDENTITY_INSERT [dbo].[Subject] ON 
INSERT [dbo].[Subject] ([SubjectID],[SubjectName]) VALUES (1,N'English')
INSERT [dbo].[Subject] ([SubjectID],[SubjectName]) VALUES (2,N'Mathematics')
SET IDENTITY_INSERT [dbo].[Subject] OFF

然后使用下面的查询来动态获取已更改的字段。从用户界面,您需要传递 AudRelID

DECLARE @TableName VARCHAR(100),@FieldName VARCHAR(100),@FieldID VARCHAR(100)

SELECT @TableName = [AudTableName],@FieldName=[AudFieldName],@FieldID=[AudFieldID] 
FROM [dbo].[AudRel] WHERE [AudId] = 1 -- (Ex : StudentHistory)


DECLARE @SQL NVARCHAR(MAX) = N'
 SELECT ID,'  + @FieldID +
','  + @FieldName + ' FROM ' +  @TableName + '_Audit ' + ' WHERE ' + @FieldID + ' = ' 
+ Convert(varchar(20),@FieldID) 

print @SQL
EXECUTE sp_executesql @SQL