2009-03-03 18 views
8

क्या यह बताने का एक अच्छा तरीका है कि SQL सर्वर 2005 में संग्रहीत प्रक्रिया किसने बनाई है (जो 2008 में भी काम करता है)? एसक्यूएल मैनेजमेंट स्टूडियो में मैं बनाई गई तारीख/समय प्राप्त करने के लिए एक proc पर सही माउस/गुण कर सकता हूं लेकिन मैं निर्माता को कैसे खोजूं?माइक्रोसॉफ्ट एसक्यूएल सर्वर - किसने संग्रहित प्रक्रिया बनाई?

+0

अच्छा एक, मिच। +1 – BuddyJoe

उत्तर

6

अब आपके लिए बहुत देर हो सकती है, लेकिन आप डीडीएल गतिविधि का ट्रैक रख सकते हैं।

हमारे पास हमारे व्यवस्थापकीय डेटाबेस में एक सारणी है जो इसमें सभी गतिविधियों को शामिल करती है। यह 2005 में नया डीडीएल ट्रिगर का उपयोग करता है। ये स्क्रिप्ट आपके व्यवस्थापक डीबी (मेरे लिए SQL_DBA) में एक टेबल बनाती हैं, मॉडल डीबी पर एक ट्रिगर बनाएं, मौजूदा डेटाबेस पर ट्रिगर्स बनाएं। मैंने उन सभी को अक्षम करने के अंत में एक sp_msforeachDB कथन भी बनाया।

एक चेतावनी - आपके डेटाबेस को 90 के संगतता मोड (प्रत्येक डीबी के विकल्पों में) होना चाहिए, अन्यथा आपको त्रुटियां मिलना शुरू हो सकता है। कथन के हिस्से के रूप में EXKUTE के खाते में भी आपके व्यवस्थापक तालिका में प्रवेश करने की आवश्यकता है।

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' 
+0

लेकिन अगर आपके पास अपनी अनुमतियां/भूमिकाएं सही तरीके से सेट की गई हैं, तो कैसे अक्सर आपको इसकी आवश्यकता होती है? –

+0

यदि आपके सिस्टम को कसकर दबाया गया है, तो आपको इसकी आवश्यकता नहीं हो सकती है। मेरे पास इस सूची को मेरे अपने उद्देश्यों के लिए प्रतिदिन मेल किया गया है, मैं इसमें शामिल नहीं होगा। – Sam

+0

+1 कूल अवधारणा। डीडीएल ट्रिगर्स के बारे में सब भूल गए। इससे भविष्य "देखने" के लिए मदद मिल सकती है। लेकिन मिच सुरक्षा के बारे में एक अच्छा मुद्दा लाता है। – BuddyJoe

3

मुझे विश्वास है कि यह SQL 2005 में उपलब्ध नहीं है। निश्चित रूप से यह SQL प्रबंधन स्टूडियो में गुणों में उपलब्ध नहीं है, और sys.objects तालिका या किसी अन्य व्यक्ति में उपलब्ध नहीं है।

3

अगर यह बहुत समय पहले नहीं बनाया गया था, इस प्रयास करें:

DECLARE @path varchar(256) 

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

SELECT * 
FROM fn_trace_gettable(@path, 1) 

यह वर्तमान डिफ़ॉल्ट ट्रेस (बॉक्स से बाहर) चयन करता है। अगर यह हाल ही में बनाया गया था (और सर्वर हाल ही में पुनरारंभ नहीं किया गया है), तो संग्रहीत प्रक्रिया ऑब्जेक्ट का नाम और लॉगिन नाम जो इसे बनाया गया है, ट्रेस डेटा में होगा।

+0

@ ब्रूनो टिंडल: तो आप कैसे गए? –

+0

यह proc 3 साल पहले बनाया गया था। मान लीजिए यह काम नहीं करेगा। साथ ही, जब मैंने इसे चलाने की कोशिश की तो मुझे "SYS.TRACES 'चलाने के लिए अनुमति नहीं है।" मान लीजिए कि मैं इसे चलाने के लिए डीबीए से पूछ सकता हूं। परंतु... – BuddyJoe

+0

मुझे लगता है कि आप जो कह रहे हैं वह निशान जानकारी केवल एक दिन, एक सप्ताह, शायद एक महीने के लिए अच्छा है? – BuddyJoe

2

सैम के रूप में एक ही विचार के साथ, आप एक DDL ट्रिगर इस्तेमाल कर सकते हैं आवश्यक जानकारी पर कब्जा करने की है, तो, एक SQL सेवा दलाल कतार में है कि डेटा भेजने व्यवस्थापक डेटाबेस को भेज सकता है जो (जिस पर हो सकता है यदि आवश्यक हो तो दूसरा सर्वर) जो तब सभी डीडीएल परिवर्तनों को पकड़ लेगा।

यह अनुमति समस्या को हटा देगा क्योंकि डीडीएल ट्रिगर स्थानीय डेटाबेस पर सेवा ब्रोकर कतार में डेटा लोड कर रहा है और एसक्यूएल संदेश को दूसरे डेटाबेस में ले जाने से संभालता है।

इस विधि के साथ थोड़ा और सेटअप होगा, लेकिन एक बार सेटअप होने पर यह कोई फर्क नहीं पड़ता कि वस्तु किसने बदल दी है।

+0

+1 यह बहुत आशाजनक लगता है – BuddyJoe

+0

यह बहुत अधिक चिकना है। अब, अगर हम डेटाबेस की एक प्रति बनाते हैं और इसे डेवलपर को देते हैं, तो उन्हें डीडीएल मोड पर त्रुटियां मिलेंगी। – Sam

0

जानकारी के इस भाग को कैसे प्राप्त करें (विशेष रूप से सालों बाद) संभवतः संभव नहीं है।

हालांकि, आप डीडीएल कार्यों को ट्रैक करने के लिए SQL सर्वर प्रोफाइलर का उपयोग कर सकते हैं। घटना चुनाव में, निम्न इवेंट की जाँच करें:

वस्तुओं/वस्तु: बदल

वस्तुओं/वस्तु: बनाया गया

वस्तुओं/वस्तु: हटाए गए

वहाँ भी अनुकूलन विकल्प के बहुत सारे हैं: यदि आप कर सकते हैं आउटपुट को किसी फ़ाइल या टेबल पर सहेजें, आउटपुट को किसी भी कॉलम इत्यादि के आधार पर फ़िल्टर करें आदि।

संबंधित मुद्दे