Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何捕获SQL中每天创建和删除的表的详细信息?_Sql_Sql Server - Fatal编程技术网

如何捕获SQL中每天创建和删除的表的详细信息?

如何捕获SQL中每天创建和删除的表的详细信息?,sql,sql-server,Sql,Sql Server,需要找出每天创建和删除的表的列表。首先,旧方法和不安全方法。服务器级DDL触发器: SELECT * FROM sys.tables WHERE create_date >= '20180712' AND create_date < '20180713' 我建议的解决方案是使用SQL Server审核: 然后,您可以使用内置视图查看所有架构更改: 或者,更灵活的方式是,您可以查询例如最后一个日志文件,并根据需要应用任何筛选器: declare @database_

需要找出每天创建和删除的表的列表。

首先,旧方法和不安全方法。服务器级DDL触发器:
 SELECT *
 FROM sys.tables
 WHERE create_date >= '20180712' AND create_date < '20180713' 

我建议的解决方案是使用SQL Server审核:

然后,您可以使用内置视图查看所有架构更改:

或者,更灵活的方式是,您可以查询例如最后一个日志文件,并根据需要应用任何筛选器:

 declare
 @database_name sysname =   N'my_database'
,@object_name   sysname =   N'my_object_name';

--  get last audit file path/name
declare @last_log_file  nvarchar(512)   =  (select [audit_file_path] from [sys].[dm_server_audit_status]);
declare @dt_from        datetime;
declare @dt_to          datetime;

--  transfer last log file into temporary table 
if object_id('tempdb..#auditlogs', 'u') is not null
begin
    drop table [#auditlogs];
end;


select * into [#auditlogs] from [sys].[fn_get_audit_file](@last_log_file, default, default);

--  get log file first/last rec dates
select 
     @dt_from   =   min([event_time])
    ,@dt_to     =   max([event_time])
from
    [#auditlogs];

--  index temporary table   
create nonclustered index [ix_#auditlogs__event_time]           on [#auditlogs]([event_time]        asc);
create nonclustered index [ix_#auditlogs__database_name]        on [#auditlogs]([database_name]     asc);
create nonclustered index [ix_#auditlogs__object_name]          on [#auditlogs]([object_name]       asc); 
create nonclustered index [ix_#auditlogs__audit_file_offset]    on [#auditlogs]([audit_file_offset] asc); 


--  display some info about the retrieved logs
select 
     [logs_from]        =   @dt_from    
    ,[logs_to]          =   @dt_to
    ,[log_file_name]    =   @last_log_file;

--  remove not actual data
delete from [#auditlogs] where 
        (nullif([database_name] , space(0)) is not null and [database_name] <> @database_name)
    or  (nullif([object_name]   , space(0)) is not null and [object_name]   <> @object_name);


--  get last audit file logs
select  
     [event_time]       =   [l].[event_time]                                    
    ,[user]             =   [l].[session_server_principal_name] + quotename([l].[server_principal_name], '(')       
    ,[action_id]        =   case [l].[action_id] 
                                when 'al'   then    'alter' 
                                when 'dr'   then    'drop' 
                                when 'cr'   then    'create' 
                                else                [l].[action_id] 
                            end                 
    ,[class_type]       =   case [l].[class_type] 
                                when 'u'    then    'table' 
                                when 'if'   then    'inline function' 
                                when 'p'    then    'procedure' 
                                when 'tr'   then    'trigger'   
                                when 'tf'   then    'table valued function' 
                                else                [l].[class_type] 
                            end                         
    ,[server_name]      =   quotename(nullif([l].[server_instance_name] , space(0)))                    
    ,[database_name]    =   quotename(nullif([l].[database_name]        , space(0)))                    
    ,[schema_name]      =   quotename(nullif([l].[schema_name]          , space(0)))                
    ,[object_name]      =   quotename(nullif([l].[object_name]          , space(0)))                
    ,[statement]        =   convert(xml, [st].[statement]).[query]('statement/text()')
from
    [#auditlogs]    as  [l]
outer apply
    (
        select [statement] = (select [statement] from [#auditlogs] where [audit_file_offset] = [l].[audit_file_offset] and [event_time] = [l].[event_time] order by [sequence_number] asc for xml path (''))
    )               as  [st]
group by
        [l].[audit_file_offset]
    ,[l].[event_time]                                   
    ,[l].[session_server_principal_name]
    ,[l].[server_principal_name]
    ,[l].[action_id]    
    ,[l].[class_type]
    ,[l].[server_instance_name] 
    ,[l].[database_name]        
    ,[l].[schema_name]          
    ,[l].[object_name]  
    ,[st].[statement]   
order by 
        [l].[event_time]    desc;

首先,陈旧而不安全的方法。服务器级DDL触发器:

我建议的解决方案是使用SQL Server审核:

然后,您可以使用内置视图查看所有架构更改:

或者,更灵活的方式是,您可以查询例如最后一个日志文件,并根据需要应用任何筛选器:

 declare
 @database_name sysname =   N'my_database'
,@object_name   sysname =   N'my_object_name';

--  get last audit file path/name
declare @last_log_file  nvarchar(512)   =  (select [audit_file_path] from [sys].[dm_server_audit_status]);
declare @dt_from        datetime;
declare @dt_to          datetime;

--  transfer last log file into temporary table 
if object_id('tempdb..#auditlogs', 'u') is not null
begin
    drop table [#auditlogs];
end;


select * into [#auditlogs] from [sys].[fn_get_audit_file](@last_log_file, default, default);

--  get log file first/last rec dates
select 
     @dt_from   =   min([event_time])
    ,@dt_to     =   max([event_time])
from
    [#auditlogs];

--  index temporary table   
create nonclustered index [ix_#auditlogs__event_time]           on [#auditlogs]([event_time]        asc);
create nonclustered index [ix_#auditlogs__database_name]        on [#auditlogs]([database_name]     asc);
create nonclustered index [ix_#auditlogs__object_name]          on [#auditlogs]([object_name]       asc); 
create nonclustered index [ix_#auditlogs__audit_file_offset]    on [#auditlogs]([audit_file_offset] asc); 


--  display some info about the retrieved logs
select 
     [logs_from]        =   @dt_from    
    ,[logs_to]          =   @dt_to
    ,[log_file_name]    =   @last_log_file;

--  remove not actual data
delete from [#auditlogs] where 
        (nullif([database_name] , space(0)) is not null and [database_name] <> @database_name)
    or  (nullif([object_name]   , space(0)) is not null and [object_name]   <> @object_name);


--  get last audit file logs
select  
     [event_time]       =   [l].[event_time]                                    
    ,[user]             =   [l].[session_server_principal_name] + quotename([l].[server_principal_name], '(')       
    ,[action_id]        =   case [l].[action_id] 
                                when 'al'   then    'alter' 
                                when 'dr'   then    'drop' 
                                when 'cr'   then    'create' 
                                else                [l].[action_id] 
                            end                 
    ,[class_type]       =   case [l].[class_type] 
                                when 'u'    then    'table' 
                                when 'if'   then    'inline function' 
                                when 'p'    then    'procedure' 
                                when 'tr'   then    'trigger'   
                                when 'tf'   then    'table valued function' 
                                else                [l].[class_type] 
                            end                         
    ,[server_name]      =   quotename(nullif([l].[server_instance_name] , space(0)))                    
    ,[database_name]    =   quotename(nullif([l].[database_name]        , space(0)))                    
    ,[schema_name]      =   quotename(nullif([l].[schema_name]          , space(0)))                
    ,[object_name]      =   quotename(nullif([l].[object_name]          , space(0)))                
    ,[statement]        =   convert(xml, [st].[statement]).[query]('statement/text()')
from
    [#auditlogs]    as  [l]
outer apply
    (
        select [statement] = (select [statement] from [#auditlogs] where [audit_file_offset] = [l].[audit_file_offset] and [event_time] = [l].[event_time] order by [sequence_number] asc for xml path (''))
    )               as  [st]
group by
        [l].[audit_file_offset]
    ,[l].[event_time]                                   
    ,[l].[session_server_principal_name]
    ,[l].[server_principal_name]
    ,[l].[action_id]    
    ,[l].[class_type]
    ,[l].[server_instance_name] 
    ,[l].[database_name]        
    ,[l].[schema_name]          
    ,[l].[object_name]  
    ,[st].[statement]   
order by 
        [l].[event_time]    desc;

每天存储sys.tables并进行比较。已删除的表未存储在系统对象中您需要每天查看store sys.tables并进行比较。已删除的表未存储在系统对象中您需要查看