8

誰が SQL Server 2005 でストアド プロシージャを作成したかを確認する良い方法はありますか (2008 でも機能します)。SQL Management Studio では、proc のマウス/プロパティを右クリックして、作成された日付/時刻を取得できますが、作成者を見つけるにはどうすればよいですか?

4

5 に答える 5

6

今では手遅れかもしれませんが、DDL アクティビティを追跡できます。

管理データベースには、すべてのアクティビティを取得するテーブルがあります。2005年に新しく追加されたDDLトリガーを使用します。これらのスクリプトは、管理DB(私にとってはSQL_DBA)にテーブルを作成し、モデルdbにトリガーを作成し、既存のデータベースにトリガーを作成します。また、最後に sp_msforeachDB ステートメントを作成して、それらをすべて無効にしました。

1 つの注意点- データベースは 90 の互換性モード (各データベースのオプション) である必要があります。そうしないと、エラーが発生する可能性があります。ステートメントの 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'
于 2009-03-04T00:36:31.990 に答える
5

あまり前に作成されていない場合は、次のことを試してください。

DECLARE @path varchar(256)

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

SELECT *
FROM fn_trace_gettable(@path, 1)

現在の (箱から出して) デフォルトのトレースを選択します。最近作成された (そしてサーバーが最近再起動されていない) 場合、ストアド プロシージャ オブジェクト名とそれを作成したログイン名がトレース データに含まれます。

于 2009-03-04T00:11:02.847 に答える
3

これは SQL 2005 では利用できないと思います。確かに、SQL Management Studio のプロパティでは利用できず、sys.objects テーブルやその他のテーブルでも利用できません。

于 2009-03-04T00:10:21.320 に答える
2

Samと同じ考え方で、DDLトリガーを使用して必要な情報を取得し、そのデータをSQLサービスブローカーキューに送信して、管理データベース(必要に応じて別のサーバー上にある可能性があります)に転送することができます。次に、すべてのDDL変更を保持します。

これにより、DDLトリガーがローカルデータベースのService Broker Queueにデータをロードし、SQLが他のデータベースへのメッセージの移動を処理するため、アクセス許可の問題が解消されます。

このメソッドではもう少しセットアップが必要になりますが、一度セットアップすると、オブジェクトを誰が変更したかに関係なく機能します。

于 2009-03-31T04:49:03.093 に答える
0

この情報を事後(特に数年後)に取得する方法は、おそらく不可能です。

ただし、SQL Server プロファイラーを使用して DDL アクションを追跡できます。[イベントの選択] で、次のイベントを確認します。

オブジェクト / オブジェクト: 変更済み

オブジェクト / オブジェクト: 作成済み

オブジェクト / オブジェクト: 削除済み

多くのカスタマイズ オプションもあります。出力をファイルまたはテーブルに保存したり、任意の列に基づいて出力をさらにフィルタリングしたりできます。

于 2009-11-19T08:55:17.320 に答える