Sql server 查找SQL Server中删除SQL视图的人员/时间
在我们的一个SQL Server数据库中,我们有许多SQL视图。每隔几周就有一个特定的视图消失,我想知道发生了什么 是否有一种方法可以查询SQL Server以找出何时以及谁删除了该视图Sql server 查找SQL Server中删除SQL视图的人员/时间,sql-server,Sql Server,在我们的一个SQL Server数据库中,我们有许多SQL视图。每隔几周就有一个特定的视图消失,我想知道发生了什么 是否有一种方法可以查询SQL Server以找出何时以及谁删除了该视图 或者,是否可以在DROPview命令上添加SQL Server触发器以捕获DROP,并使其失败?是的,这是一个DDL触发器。MSDN文章中包含了关于此类触发器的示例触发器文本。我想说,出于审计的原因,这样的触发器是生产数据库上必须的 另一个技巧是使用SCHEMA\u BINDING选项创建依赖于此对象(视图)
或者,是否可以在
DROP
view命令上添加SQL Server触发器以捕获DROP
,并使其失败?是的,这是一个DDL触发器。MSDN文章中包含了关于此类触发器的示例触发器文本。我想说,出于审计的原因,这样的触发器是生产数据库上必须的
另一个技巧是使用
SCHEMA\u BINDING
选项创建依赖于此对象(视图)的另一个对象(视图?)。这将使得无法删除任何对象架构绑定的对象所依赖的对象。是的,这是一个DDL触发器。MSDN文章中包含了关于此类触发器的示例触发器文本。我想说,出于审计的原因,这样的触发器是生产数据库上必须的
另一个技巧是使用
SCHEMA\u BINDING
选项创建依赖于此对象(视图)的另一个对象(视图?)。这将使得无法删除任何对象模式绑定对象所依赖的对象。此信息将写入默认跟踪。下面是一个收集信息的查询示例
SELECT
te.name
,tt.DatabaseName
,tt.StartTime
,tt.HostName
,tt.LoginName
,tt.ApplicationName
,tt.LoginName
FROM sys.traces AS t
CROSS APPLY fn_trace_gettable(
--get trace folder and add base file name log.trc
REVERSE(SUBSTRING(REVERSE(t.path), CHARINDEX(N'\', REVERSE(t.path)), 128)) + 'log.trc', default) AS tt
JOIN sys.trace_events AS te ON
te.trace_event_id = tt.EventClass
JOIN sys.trace_subclass_values AS tesv ON
tesv.trace_event_id = tt.EventClass
AND tesv.subclass_value = tt.EventSubClass
WHERE
t.is_default = 1 --default trace
AND tt.ObjectName = N'YourView'
AND tt.DatabaseName = N'YourDatabase';
注意:默认跟踪是一个滚动跟踪,最大保留100MB,因此如果不久前重新创建视图,它可能没有法医信息。此信息将写入默认跟踪。下面是一个收集信息的查询示例
SELECT
te.name
,tt.DatabaseName
,tt.StartTime
,tt.HostName
,tt.LoginName
,tt.ApplicationName
,tt.LoginName
FROM sys.traces AS t
CROSS APPLY fn_trace_gettable(
--get trace folder and add base file name log.trc
REVERSE(SUBSTRING(REVERSE(t.path), CHARINDEX(N'\', REVERSE(t.path)), 128)) + 'log.trc', default) AS tt
JOIN sys.trace_events AS te ON
te.trace_event_id = tt.EventClass
JOIN sys.trace_subclass_values AS tesv ON
tesv.trace_event_id = tt.EventClass
AND tesv.subclass_value = tt.EventSubClass
WHERE
t.is_default = 1 --default trace
AND tt.ObjectName = N'YourView'
AND tt.DatabaseName = N'YourDatabase';
注意:默认跟踪是一个最大保持100MB的滚动跟踪,因此如果不久前重新创建了视图,它可能没有法医信息。要扩展另一个答案,下面是一些代码,用于
DROP\u view
的DDL触发器。例如,假设有人从AdventureWorks
数据库中删除了视图[HumanResources].[vEmployee]
。EVENTDATA()
的外观如下:
<EVENT_INSTANCE>
<EventType>DROP_VIEW</EventType>
<PostTime>2016-02-26T09:02:58.190</PostTime>
<SPID>60</SPID>
<ServerName>YourSqlHost\SQLEXPRESS</ServerName>
<LoginName>YourDomain\SomeLogin</LoginName>
<UserName>dbo</UserName>
<DatabaseName>AdventureWorks2012</DatabaseName>
<SchemaName>HumanResources</SchemaName>
<ObjectName>vEmployee</ObjectName>
<ObjectType>VIEW</ObjectType>
<TSQLCommand>
<SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" />
<CommandText>DROP VIEW [HumanResources].[vEmployee]
</CommandText>
</TSQLCommand>
</EVENT_INSTANCE>
为了扩展另一个答案,下面是一些代码,可以从
DROP\u VIEW
的DDL触发器开始。例如,假设有人从AdventureWorks
数据库中删除了视图[HumanResources].[vEmployee]
。EVENTDATA()
的外观如下:
<EVENT_INSTANCE>
<EventType>DROP_VIEW</EventType>
<PostTime>2016-02-26T09:02:58.190</PostTime>
<SPID>60</SPID>
<ServerName>YourSqlHost\SQLEXPRESS</ServerName>
<LoginName>YourDomain\SomeLogin</LoginName>
<UserName>dbo</UserName>
<DatabaseName>AdventureWorks2012</DatabaseName>
<SchemaName>HumanResources</SchemaName>
<ObjectName>vEmployee</ObjectName>
<ObjectType>VIEW</ObjectType>
<TSQLCommand>
<SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" />
<CommandText>DROP VIEW [HumanResources].[vEmployee]
</CommandText>
</TSQLCommand>
</EVENT_INSTANCE>
您还可以在服务器级别创建一个数据库,以便捕获和记录数据库上的更改:
CREATE TRIGGER [Trg_AuditStoredProcedures_Data]
ON ALL SERVER
FOR CREATE_PROCEDURE,ALTER_PROCEDURE,DROP_PROCEDURE,CREATE_TABLE,ALTER_TABLE,
DROP_TABLE,CREATE_FUNCTION,ALTER_FUNCTION,DROP_FUNCTION,CREATE_VIEW,ALTER_VI EW,
DROP_VIEW,CREATE_DATABASE,DROP_DATABASE,ALTER_DATABASE,
CREATE_TRIGGER,DROP_TRIGGER,ALTER_TRIGGER
AS
SET ANSI_PADDING ON
DECLARE @eventdata XML;
SET @eventdata = EVENTDATA();
SET NOCOUNT ON
/*Create table AuditDatabaseObject in order to have a history tracking for every DDL change on the database*/
INSERT INTO AuditDatabaseObject
(DatabaseName,ObjectName,LoginName,ChangeDate,EventType,EventDataXml,HostName)
VALUES (
@eventdata.value('(/EVENT_INSTANCE/DatabaseName)[1]','sysname')
, @eventdata.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname')
, @eventdata.value('(/EVENT_INSTANCE/LoginName)[1]', 'sysname')
, GETDATE()
, @eventdata.value('(/EVENT_INSTANCE/EventType)[1]', 'sysname')
, @eventdata
, HOST_NAME()
);
DECLARE @Valor VARCHAR(30),@EvenType VARCHAR(30)
SET @Valor = @eventdata.value('(/EVENT_INSTANCE/LoginName)[1]', 'sysname')
SET @EvenType = @eventdata.value('(/EVENT_INSTANCE/EventType)[1]', 'sysname')
IF (IS_SRVROLEMEMBER('sysadmin',@Valor) != 1 AND @EvenType = 'DROP_DATABASE')
BEGIN
ROLLBACK
END
你可以在这里找到更多信息
如果从数据库中删除对象,您将看到在表AuditDatabaseObject上创建的记录
还要记住@Chris Pickford提到的安全性。您还可以在服务器级别创建一个数据库,以便捕获并记录数据库上的更改:
CREATE TRIGGER [Trg_AuditStoredProcedures_Data]
ON ALL SERVER
FOR CREATE_PROCEDURE,ALTER_PROCEDURE,DROP_PROCEDURE,CREATE_TABLE,ALTER_TABLE,
DROP_TABLE,CREATE_FUNCTION,ALTER_FUNCTION,DROP_FUNCTION,CREATE_VIEW,ALTER_VI EW,
DROP_VIEW,CREATE_DATABASE,DROP_DATABASE,ALTER_DATABASE,
CREATE_TRIGGER,DROP_TRIGGER,ALTER_TRIGGER
AS
SET ANSI_PADDING ON
DECLARE @eventdata XML;
SET @eventdata = EVENTDATA();
SET NOCOUNT ON
/*Create table AuditDatabaseObject in order to have a history tracking for every DDL change on the database*/
INSERT INTO AuditDatabaseObject
(DatabaseName,ObjectName,LoginName,ChangeDate,EventType,EventDataXml,HostName)
VALUES (
@eventdata.value('(/EVENT_INSTANCE/DatabaseName)[1]','sysname')
, @eventdata.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname')
, @eventdata.value('(/EVENT_INSTANCE/LoginName)[1]', 'sysname')
, GETDATE()
, @eventdata.value('(/EVENT_INSTANCE/EventType)[1]', 'sysname')
, @eventdata
, HOST_NAME()
);
DECLARE @Valor VARCHAR(30),@EvenType VARCHAR(30)
SET @Valor = @eventdata.value('(/EVENT_INSTANCE/LoginName)[1]', 'sysname')
SET @EvenType = @eventdata.value('(/EVENT_INSTANCE/EventType)[1]', 'sysname')
IF (IS_SRVROLEMEMBER('sysadmin',@Valor) != 1 AND @EvenType = 'DROP_DATABASE')
BEGIN
ROLLBACK
END
你可以在这里找到更多信息
如果从数据库中删除对象,您将看到在表AuditDatabaseObject上创建的记录
还要记住@Chris Pickford提到的安全性。问问自己,“谁需要能够删除数据库对象?”。将对数据库的权限限制为这些人/帐户。我正是为此目的启动了一项服务。问问自己,“谁需要能够删除数据库对象?”。将对数据库的权限限制为这些人/帐户。我正是为此目的启动了一项服务。谢谢,这使我更进一步。查询显示该视图在几天前被删除,并且是通过哪个登录名和哪个应用程序删除的。谢谢,这让我更进一步。该查询显示该视图在几天前被删除,以及由哪个登录名和哪个应用程序删除。