Pergunta

Existe uma boa maneira de dizer que criou um procedimento armazenado no SQL Server 2005 (que também funciona em 2008)? Em SQL Management Studio eu posso botão direito do mouse / propriedades em um proc para obter a data / hora de criação, mas como faço para descobrir o criador?

Foi útil?

Solução

Pode ser tarde demais para você agora, mas você pode manter o controle de atividade DDL.

Temos uma tabela em nosso banco de dados administrativo que recebe toda a atividade de colocar nele. Ele usa um gatilho DDL, novo para 2005. Esses scripts criar uma tabela no seu administrador DB (SQL_DBA para mim), crie um gatilho no modelo db, criar gatilhos das bases de dados existentes. Eu também criou uma declaração sp_msforeachDB no final para desativar todos eles.

Uma ressalva - seus bancos de dados precisam estar em modo de compatibilidade de 90 (em opções para cada db), caso contrário você pode começar a receber erros. A conta na parte EXECUTAR AS da declaração também precisa de acesso para inserir em sua mesa de administração.

USE [SQL_DBA]
GO
/****** Object:  Table [dbo].[DDL_Login_Log]    Script Date: 03/03/2009 17:28:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[DDL_Login_Log](
    [DDL_Id] [int] IDENTITY(1,1) NOT NULL,
    [PostTime] [datetime] NOT NULL,
    [DB_User] [nvarchar](100) NULL,
    [DBName] [nvarchar](100) NULL,
    [Event] [nvarchar](100) NULL,
    [TSQL] [nvarchar](2000) NULL,
    [Object] [nvarchar](1000) NULL,
 CONSTRAINT [PK_DDL_Login_Log] PRIMARY KEY CLUSTERED 
(
    [DDL_Id] ASC,
    [PostTime] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--This creates the trigger on the model database so all new DBs get it
USE [model]
GO
/****** Object:  DdlTrigger [ddl_DB_User]    Script Date: 03/03/2009 17:26:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [ddl_DB_User] 
ON DATABASE
FOR DDL_DATABASE_SECURITY_EVENTS
AS 

DECLARE @data XML
declare @user nvarchar(100)

SET @data = EVENTDATA()
select @user = convert(nvarchar(100), SYSTEM_USER)

execute as login='domain\sqlagent'
INSERT sql_dba.dbo.DDL_Login_Log 
   (PostTime, DB_User, DBName, Event, TSQL,Object) 
   VALUES 
   (@data.value('(/EVENT_INSTANCE/PostTime)[1]', 'nvarchar(100)'), 
   @user,
    db_name(),
    @data.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)'), 
   @data.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)'),
    @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(1000)')
)

GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--CREATE TRIGGER IN ALL NON SYSTEM DATABASES

DECLARE @dataname varchar(255),
@dataname_header varchar(255),
@command VARCHAR(MAX),
@usecommand VARCHAR(100)
SET @command = '';
DECLARE datanames_cursor CURSOR FOR SELECT name FROM sys.databases 
WHERE name not in ('master', 'pubs', 'tempdb', 'model','msdb')
OPEN datanames_cursor
FETCH NEXT FROM datanames_cursor INTO @dataname
WHILE (@@fetch_status = 0)
BEGIN

PRINT '----------BEGIN---------'

PRINT 'DATANAME variable: ' + @dataname;

EXEC ('USE ' + @dataname);

PRINT 'CURRENT db: ' + db_name();

SELECT @command = 'CREATE TRIGGER DBA_Audit ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS
AS
DECLARE @data XML
DECLARE @cmd NVARCHAR(1000)
DECLARE @posttime NVARCHAR(24)
DECLARE @spid NVARCHAR(6)
DECLARE @loginname NVARCHAR(100)
DECLARE @hostname NVARCHAR(100)
SET @data = EVENTDATA()
SET @cmd = @data.value(''(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]'', ''NVARCHAR(1000)'')
SET @cmd = LTRIM(RTRIM(REPLACE(@cmd,'''','''')))
SET @posttime = @data.value(''(/EVENT_INSTANCE/PostTime)[1]'', ''DATETIME'')
SET @spid = @data.value(''(/EVENT_INSTANCE/SPID)[1]'', ''nvarchar(6)'')
SET @loginname = @data.value(''(/EVENT_INSTANCE/LoginName)[1]'',
    ''NVARCHAR(100)'')
SET @hostname = HOST_NAME()
INSERT INTO [DBA_AUDIT].dbo.AuditLog(Command, PostTime,HostName,LoginName)
 VALUES(@cmd, @posttime, @hostname, @loginname);'

 EXEC (@command);
 FETCH NEXT FROM datanames_cursor INTO @dataname;
PRINT '----------END---------'
END
CLOSE datanames_cursor
DEALLOCATE datanames_cursor

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

----Disable all triggers when things go haywire
sp_msforeachdb @command1='use [?]; IF  EXISTS (SELECT * FROM sys.triggers WHERE name = N''ddl_DB_User'' AND parent_class=0)disable TRIGGER [ddl_DB_User] ON DATABASE'

Outras dicas

Eu acredito que este não está disponível em SQL 2005. Certamente ele não está disponível nas propriedades no SQL Server Management Studio, e não disponíveis na tabela de sys.objects ou quaisquer outros que eu posso ver.

Se não foi criado há muito tempo, tente o seguinte:

DECLARE @path varchar(256)

SELECT @path = path
FROM sys.traces
where id = 1

SELECT *
FROM fn_trace_gettable(@path, 1)

Ele seleciona a corrente (fora da caixa) rastreamento padrão. Se ele foi criado recentemente (eo servidor não foi reiniciado recentemente), em seguida, o nome do objeto procedimento armazenado e o nome de login que o criou será na dados de rastreamento.

Ao longo da mesma idéia que Sam, você poderia usar um gatilho DDL para capturar a informação necessária, em seguida, enviar os dados para um serviço SQL corretor fila, o que poderia enviá-lo para o banco de dados de administração (que poderia ser em outro servidor, se necessário ), que passaria a deter todas as alterações DDL.

Isso eliminaria as permissões emitir como o gatilho DDL seria carregar dados em um Service Broker fila no banco de dados local e SQL lida com o movimento da mensagem para o outro banco de dados.

Não seria um pouco mais de configuração com este método, mas assim que a configuração que iria funcionar, não importa quem fez a alteração objeto.

Como obter este pedaço de informação ex post (especialmente anos depois) provavelmente não é possível.

No entanto, você pode usar o SQL Server Profiler para rastrear as ações DDL. Em Seleção de Eventos, verifique os seguintes eventos:

Objetos / Objeto: Altered

Objetos / Objeto: Criado

Objetos / Objeto: Deleted

Há também muitas opções de personalização:. Você pode salvar a saída para um arquivo ou tabela, filtro de saída, além disso, com base em quaisquer colunas etc etc

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top