Chi ha creato una procedura? (SQL Server 2008 R2)


10

C'è un modo per elencare chi ha creato determinati procure in SQL Server 2008?

In questo link SO ci sono alcune risposte ma di 6 anni fa.

So che è una buona pratica scrivere il tuo nome e la tua data, quindi iniziare a creare la procedura, ma non vedo dove lavoro.

Se non è possibile eseguire questa operazione, è possibile eseguire questa attività con i trigger?

E una domanda bonus. È questo il lavoro di un dba? sapere chi l'ha creato?

Grazie mille.

Risposte:


7

Sì, c'è un modo

La tabella per memorizzare i risultati del trigger

USE [SOME_DATABASE]
GO

CREATE TABLE [dbo].[ddl_objects_log](
    [date] [datetime] NULL DEFAULT (getdate()),
    [login_name] [nvarchar](128) NULL,
    [nt_user_name] [nvarchar](128) NULL,
    [program_name] [nvarchar](128) NULL,
    [host_name] [nvarchar](128) NULL,
    [text] [xml] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

Il grilletto

USE [SOME_DATABASE]
GO

/****** Object:  DdlTrigger [ddl_db_trigger]    Script Date: 22/01/2015 13:41:38 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TRIGGER [ddl_db_trigger]
ON DATABASE
FOR CREATE_FUNCTION,
    CREATE_PROCEDURE,
    CREATE_TABLE,
    CREATE_TRIGGER,
    CREATE_VIEW,
    ALTER_FUNCTION,
    ALTER_PROCEDURE,
    ALTER_TABLE,
    ALTER_TRIGGER,
    ALTER_VIEW,
    DROP_FUNCTION,
    DROP_PROCEDURE,
    DROP_TABLE,
    DROP_TRIGGER,
    DROP_VIEW,
    CREATE_INDEX,
    ALTER_INDEX,
    DROP_INDEX
AS 
BEGIN
set nocount ON
    insert into ddl_objects_log(login_name, nt_user_name, program_name, host_name, text)
    select login_name, nt_user_name, program_name, host_name, EVENTDATA() from sys.dm_exec_sessions WITH(NOLOCK) where session_id=@@SPID
set nocount OFF
END

GO

ENABLE TRIGGER [ddl_db_trigger] ON DATABASE
GO

La query per controllare i risultati del trigger

USE [SOME_DATABASE]
GO


SELECT top 10
REPLACE(CONVERT(VARCHAR(250), text.query('data(/EVENT_INSTANCE/PostTime)')),'T', ' ') as modify_datetime,
CONVERT(VARCHAR(215), text.query('data(/EVENT_INSTANCE/EventType)')) as event_type,
CONVERT(VARCHAR(225), text.query('data(/EVENT_INSTANCE/ServerName)')) as server_name,
CONVERT(VARCHAR(225), text.query('data(/EVENT_INSTANCE/DatabaseName)')) as database_name,
CONVERT(VARCHAR(225), text.query('data(/EVENT_INSTANCE/ObjectType)')) as object_type,
CONVERT(VARCHAR(225), text.query('data(/EVENT_INSTANCE/ObjectName)')) as object_name,
CONVERT(VARCHAR(215), text.query('data(/EVENT_INSTANCE/UserName)')) as user_name,
Login_name,
CONVERT(VARCHAR(MAX), text.query('data(/EVENT_INSTANCE/TSQLCommand/CommandText)')) as command_text
FROM [SOME_DATABASE].[dbo].[ddl_objects_log]
where CONVERT(VARCHAR(225), text.query('data(/EVENT_INSTANCE/ObjectName)')) like '%SOME_STORED_PROCEDURE%'
order by date desc
GO

Un altro DBA potrebbe avere un'opinione diversa, ma ritengo che avere queste informazioni prontamente disponibili sia importante per un DBA.


Ciao. Grazie per la risposta veloce. Farò un piccolo test qui.
Racer SQL,

@craig ... Sto riscontrando problemi qui FROM [SOME_DATABASE].[dbo].[ddl_objects_log]... Devo creare la tabella?
Racer SQL,

Ciò è possibile se esiste un trigger esistente che lo registrerà. La traccia predefinita (a meno che tu non l'abbia disabilitato esplicitamente) è già in esecuzione e acquisisce gli eventi (a meno che non venga capovolta e le informazioni non siano più disponibili).
Kin Shah,

@RafaelPiccinelli Ho aggiunto il codice SQL della tabella
Craig Efrein

Grazie @CraigEfrein ... @ kin, ho "default trace enabled = 1". Non ho capito il tuo commento. Questo trigger funzionerà solo se ho già un altro trigger? Mi dispiace, sono una novità nel mondo della sicurezza.
Racer SQL,

3

Se la traccia predefinita è abilitata e non è stata sottoposta a rollover, è possibile utilizzarla per trovare chi ha creato l'SP

/*
    Object Altered
    Object Created
    Object Deleted 
*/

SELECT  TE.name ,

        v.subclass_name ,

        DB_NAME(t.DatabaseId) AS DBName ,

        T.NTDomainName ,

        t.NTUserName ,

        t.HostName ,

        t.ApplicationName ,

        t.LoginName ,

        t.Duration ,

        t.StartTime ,

        t.ObjectName ,

        CASE t.ObjectType

          WHEN 8259 THEN 'Check Constraint'

          WHEN 8260 THEN 'Default (constraint or standalone)'

          WHEN 8262 THEN 'Foreign-key Constraint'

          WHEN 8272 THEN 'Stored Procedure'

          WHEN 8274 THEN 'Rule'

          WHEN 8275 THEN 'System Table'

          WHEN 8276 THEN 'Trigger on Server'

          WHEN 8277 THEN '(User-defined) Table'

          WHEN 8278 THEN 'View'

          WHEN 8280 THEN 'Extended Stored Procedure'

          WHEN 16724 THEN 'CLR Trigger'

          WHEN 16964 THEN 'Database'

          WHEN 16975 THEN 'Object'

          WHEN 17222 THEN 'FullText Catalog'

          WHEN 17232 THEN 'CLR Stored Procedure'

          WHEN 17235 THEN 'Schema'

          WHEN 17475 THEN 'Credential'

          WHEN 17491 THEN 'DDL Event'

          WHEN 17741 THEN 'Management Event'

          WHEN 17747 THEN 'Security Event'

          WHEN 17749 THEN 'User Event'

          WHEN 17985 THEN 'CLR Aggregate Function'

          WHEN 17993 THEN 'Inline Table-valued SQL Function'

          WHEN 18000 THEN 'Partition Function'

          WHEN 18002 THEN 'Replication Filter Procedure'

          WHEN 18004 THEN 'Table-valued SQL Function'

          WHEN 18259 THEN 'Server Role'

          WHEN 18263 THEN 'Microsoft Windows Group'

          WHEN 19265 THEN 'Asymmetric Key'

          WHEN 19277 THEN 'Master Key'

          WHEN 19280 THEN 'Primary Key'

          WHEN 19283 THEN 'ObfusKey'

          WHEN 19521 THEN 'Asymmetric Key Login'

          WHEN 19523 THEN 'Certificate Login'

          WHEN 19538 THEN 'Role'

          WHEN 19539 THEN 'SQL Login'

          WHEN 19543 THEN 'Windows Login'

          WHEN 20034 THEN 'Remote Service Binding'

          WHEN 20036 THEN 'Event Notification on Database'

          WHEN 20037 THEN 'Event Notification'

          WHEN 20038 THEN 'Scalar SQL Function'

          WHEN 20047 THEN 'Event Notification on Object'

          WHEN 20051 THEN 'Synonym'

          WHEN 20549 THEN 'End Point'

          WHEN 20801 THEN 'Adhoc Queries which may be cached'

          WHEN 20816 THEN 'Prepared Queries which may be cached'

          WHEN 20819 THEN 'Service Broker Service Queue'

          WHEN 20821 THEN 'Unique Constraint'

          WHEN 21057 THEN 'Application Role'

          WHEN 21059 THEN 'Certificate'

          WHEN 21075 THEN 'Server'

          WHEN 21076 THEN 'Transact-SQL Trigger'

          WHEN 21313 THEN 'Assembly'

          WHEN 21318 THEN 'CLR Scalar Function'

          WHEN 21321 THEN 'Inline scalar SQL Function'

          WHEN 21328 THEN 'Partition Scheme'

          WHEN 21333 THEN 'User'

          WHEN 21571 THEN 'Service Broker Service Contract'

          WHEN 21572 THEN 'Trigger on Database'

          WHEN 21574 THEN 'CLR Table-valued Function'

          WHEN 21577

          THEN 'Internal Table (For example, XML Node Table, Queue Table.)'

          WHEN 21581 THEN 'Service Broker Message Type'

          WHEN 21586 THEN 'Service Broker Route'

          WHEN 21587 THEN 'Statistics'

          WHEN 21825 THEN 'User'

          WHEN 21827 THEN 'User'

          WHEN 21831 THEN 'User'

          WHEN 21843 THEN 'User'

          WHEN 21847 THEN 'User'

          WHEN 22099 THEN 'Service Broker Service'

          WHEN 22601 THEN 'Index'

          WHEN 22604 THEN 'Certificate Login'

          WHEN 22611 THEN 'XMLSchema'

          WHEN 22868 THEN 'Type'

          ELSE 'Hmmm???'

        END AS ObjectType

FROM    [fn_trace_gettable](CONVERT(VARCHAR(150), ( SELECT TOP 1

                                                            value

                                                    FROM    [fn_trace_getinfo](NULL)

                                                    WHERE   [property] = 2

                                                  )), DEFAULT) T

        JOIN sys.trace_events TE ON T.EventClass = TE.trace_event_id

        JOIN sys.trace_subclass_values v ON v.trace_event_id = TE.trace_event_id

                                            AND v.subclass_value = t.EventSubClass

WHERE   TE.name IN ( 'Object:Created', 'Object:Deleted', 'Object:Altered' )

                -- filter statistics created by SQL server                                         

        AND t.ObjectType NOT IN ( 21587 )

                -- filter tempdb objects

        AND DatabaseID <> 2

                -- get only events in the past 24 hours

        AND StartTime > DATEADD(HH, -24, GETDATE())

ORDER BY t.StartTime DESC ;

Clicca qui per ingrandire

inserisci qui la descrizione dell'immagine

È questo il lavoro di un dba? sapere chi ha creato cosa all'interno di sql?

Dipende dal motivo per cui si desidera sapere se gli oggetti vengono creati / modificati o eliminati. Puoi utilizzare la notifica degli eventi per registrarti e avvisarti se ritieni che gli oggetti vengano creati / rilasciati o modificati da un utente non autorizzato. Assicurati di disporre di filtri adeguati.

inserisci qui la descrizione dell'immagine

Per completezza di questa risposta, voglio menzionare: quali informazioni sull'evento posso ottenere di default da SQL Server? di Aaron Bertrand.


ciao @kin. Sto riscontrando problemi nel "convert". Ma cosa c'è che non va? Dice errore di sintassi.
Racer SQL,

@RafaelPiccinelli su quale riga stai ricevendo un errore? L'ho provato e non ho riscontrato alcun errore. È inoltre necessario modificare DATEADD(HH, -24, GETDATE())se si desidera ottenere risultati per più di 24 ore.
Kin Shah,

scusa, non so che cosa non andava. Ho appena copiato / passato di nuovo e funziona. Se commento questa riga, posso ottenere tutte le procedure di un determinato database, usando ad esempio `AND DatabaseID = 224`?
Racer SQL,

@RafaelPiccinelli Sono contento che funzioni. Se commenti quella riga (che è un filtro) otterrai tutti i risultati. Basta giocare con i filtri per ottenere i risultati desiderati: filtrare per dbid / dbname o anche per nome SP. Questo non ti darà l'utente che ha creato l'SP, ma ti darà il tempo quando è stato creato un SP -select * from sys.procedures where type = 'P' order by create_date desc
Kin Shah

Grazie @Kin lo sto usando in questo momento. Non voglio davvero essere fastidioso, ma perché sto ottenendo solo i risultati di 1 database? Sto usando la query pubblicata qui (quella grande) ma vedo solo un database. Se uso AND DatabaseID= 'the_Database_I_Want, non mi mostra nulla, anche con DATEADD(HH, -24, GETDATE())commenti. Sto facendo qualcosa di sbagliato?
Racer SQL,

3

Arrivo tardi, ma "faccio" sicurezza e * cose amministrative.

È questo il lavoro di un dba? sapere chi ha creato cosa all'interno di sql?

SI . È importante avere o creare questi registri ove possibile. Tuttavia, a mio avviso, è anche tua responsabilità non "aprire questa casella" fino a quando non diventa importante. In altre parole - di nuovo, a mio avviso - è tuo compito fornire il repository per i dati, assicurarti che sia sicuro, assicurati che sia sintonizzato ... e quindi stai lontano dai dati all'interno a meno che tu non sia chiamato in modo specifico guardalo o se non è necessario per raggiungere il tuo obiettivo.

La mia opinione e il mio punto di vista, ma ho trattato dati sensibili e confidenziali per molti anni e non ho quasi mai [1] "aperto la scatola", poiché ciò degrada la fiducia con gli utenti.

Ora lasciami prendere una strada diversa : cosa succede se nessuno può capire rapidamente come la procedura risponde ai casi limite? Ciò che potrebbe richiedere a te o un'ora un'ora di puzzle potrebbe richiedere all'autore alcuni minuti: "ah, giusto, questa cosa fallisce quando ..."

  1. C'era una e una sola eccezione. Nel 2007, ho notato un sacco di attività di rete sul segmento. L'ho lasciato andare per un giorno e poi ho indagato, poiché proveniva dalla macchina di una persona che sembrava essere fuori dall'ufficio più che dentro. Il giorno in questione, è andata via per metà giornata, quindi la mia mano è stata forzata . Si scopre che stava scaricando CD da Limewire e Bearshare per il suo prossimo matrimonio. L'ho consegnato al suo capo per una discussione. Decise di non fare nulla, ma pensavo che avrebbe dovuto almeno saperlo, poiché metteva l'organizzazione a rischio di azioni legali.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.