Есть ли хороший способ узнать, кто создал хранимую процедуру в SQL Server 2005 (что также работает в 2008 году)? В SQL Management Studio я могу править мышь/свойства на proc, чтобы получить созданную дату/время, но как я могу открыть создателя?Microsoft SQL Server - Кто создал хранимую процедуру?
ответ
Возможно, вам уже слишком поздно, но вы можете отслеживать активность DDL.
У нас есть таблица в нашей административной базе данных, которая получает всю деятельность, введенную в нее. Он использует триггер DDL, новый к 2005 году. Эти сценарии создают таблицу в вашем админ-DB (SQL_DBA для меня), создают триггер на модели db, создают триггеры в существующих базах данных. Я также создал заявление sp_msforeachDB в конце, чтобы отключить все из них.
Одно из предостережений - ваши базы данных должны быть в режиме совместимости 90 (в вариантах для каждого db), иначе вы можете начать получать ошибки. Учетная запись в EXECUTE AS также должна иметь доступ к вставке в вашу таблицу администратора.
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'
Но если у вас есть правильные настройки/роли, как часто вам это нужно? –
Если ваша система застегнута, вы можете не нуждаться в этом. У меня есть этот список, который ежедневно отправляется мне по почте для моих целей, в которые я не войду. – Sam
+1 Прохладный концепции. Забыл все о DDL Triggers. Это может помочь будущему «наблюдению». Но Митч хорошо разбирается в безопасности. – BuddyJoe
Я считаю, что это недоступно в SQL 2005. Конечно, он недоступен в свойствах в SQL Management Studio и недоступен в таблице sys.objects или каких-либо других, которые я вижу.
Если он не был создан слишком давно, попробуйте следующее:
DECLARE @path varchar(256)
SELECT @path = path
FROM sys.traces
where id = 1
SELECT *
FROM fn_trace_gettable(@path, 1)
Он выбирает текущий (из коробки) трассировки по умолчанию. Если он был создан недавно (и сервер не был перезапущен недавно), то имя объекта хранимой процедуры и имя пользователя, которое его создало, будут в данных трассировки.
@Bruno Tyndall: как ты ушел? –
Этот процесс был создан 3 года назад. Думаю, это не сработает. Кроме того, когда я пытался запустить его, я получил: «У вас нет разрешения на запуск« SYS.TRACES ». Думаю, я мог бы попросить администратора базы данных запустить его. Но... – BuddyJoe
Я думаю, что вы говорите, информация о трассировке хороша только около дня, недели, может быть, месяца? – BuddyJoe
По той же идее, Сэм, вы можете использовать триггер DDL, чтобы захватить необходимую информацию, а затем отправить эти данные в очередь брокера SQL Service, которые могли бы направить его в базу данных администратора (который может быть другой сервер, если это необходимо), который затем будет содержать все изменения DDL.
Это устранит проблему с разрешениями, поскольку триггер DDL будет загружать данные в очередь Service Broker в локальной базе данных, а SQL обрабатывает перемещение сообщения в другую базу данных.
С этим методом будет немного больше настроек, но после установки он будет работать независимо от того, кто изменил объект.
Как получить этот кусок информации ex post (особенно лет спустя), скорее всего, невозможно.
Однако вы можете использовать Profiler SQL Server для отслеживания действий DDL. В выборку событий, проверьте следующие события:
Объекты/Объект: Altered
Объекты/Объект: Созданный
объектов/Object: Deleted
Есть также много вариантов настройки: вы можете сохранить выход в файл или таблицу, фильтровать вывод дальше на основе любых столбцов и т. д. и т. д.
Хорошо, Митч. +1 – BuddyJoe