有沒有一種很好的方法可以告訴誰在SQL Server 2005中創建了一個存儲過程(2008年也可以)?在SQL Management Studio中,我可以在一個proc上使用鼠標/屬性來獲取創建的日期/時間,但是如何找到創建者?Microsoft SQL Server - 誰創建了存儲過程?
回答
現在對您來說可能已經太遲了,但您可以跟蹤DDL活動。
我們在我們的管理數據庫中有一個表格,它可以獲取所有的活動。它使用了一個DDL觸發器,這是2005年新增的。這些腳本在管理數據庫中創建一個表(SQL_DBA),在模型數據庫上創建觸發器,在現有數據庫上創建觸發器。我還在最後創建了一個sp_msforeachDB語句來禁用所有這些語句。
一個注意事項 - 您的數據庫需要處於兼容模式(每個數據庫的選項爲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'
我相信這在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)
它選擇當前(開箱)默認跟蹤。如果它是最近創建的(並且服務器最近尚未重新啓動),則存儲過程對象名稱和創建它的登錄名將位於跟蹤數據中。
沿着相同的思路山姆,你可以使用一個DDL觸發器來捕捉所需要的信息,然後發送數據到SQL服務代理隊列,這可能將其轉發給管理數據庫(這可能是上另一個服務器,如果需要的話),然後將保存所有的DDL變化。
這將刪除權限問題,因爲DDL觸發器將數據加載到本地數據庫的Service Broker隊列中,並且SQL處理將消息移動到其他數據庫。
用這種方法會有更多的設置,但是一旦設置它就可以工作,不管是誰改變了對象。
如何獲得這條信息事後(特別是幾年後)很可能是不可能的。
但是,您可以使用SQL Server Profiler來跟蹤DDL操作。在事件選擇,檢查以下項目:
對象/對象:改變了
對象/對象:創建
對象/對象:刪除
也有大量的定製選項:可以將輸出保存到文件或表格中,並根據任何列等過濾輸出等。
- 1. 創建存儲過程SQL Server錯誤
- 2. 爲SQL Server存儲過程創建xml
- 3. 在SQL Server中創建存儲過程
- 4. 誰更新了存儲過程?
- 5. 創建存儲過程 - SQL
- 6. SQL Server存儲過程來了空
- 7. 找出誰修改了存儲過程
- 8. 存儲過程從動態sql創建存儲過程
- 9. 如果在sql server中不存在,則創建存儲過程
- 10. Microsoft SQL Server在存儲過程中使用過時的值
- 11. 如何在存儲過程中創建過濾索引(SQL Server)
- 12. SQL動態創建存儲過程?
- 13. 存儲過程SQL Server
- 14. Sql server存儲過程
- 15. SQL Server存儲過程sp_executesql
- 16. sql server 2000存儲過程
- 17. SQL Server 2005存儲過程
- 18. 與SQL Server存儲過程
- 19. SQL Server的存儲過程
- 20. SQL Server存儲過程
- 21. SQL Server存儲過程
- 22. 慢存儲過程 - SQL Server
- 23. ASP.NET SQL Server存儲過程
- 24. SQL Server存儲過程
- 25. SQL Server存儲過程
- 26. Doctrine + SQL Server存儲過程
- 27. SQL Server存儲過程
- 28. 存儲過程和SQL Server
- 29. SQL Server 2008存儲過程
- 30. SQL Server:存儲過程存儲錯誤
好的,米奇。 +1 – BuddyJoe 2014-01-07 15:01:57