Qui a créé une procédure? (SQL Server 2008 R2)

10

Existe-t-il un moyen de répertorier qui a créé certains achats dans SQL Server 2008?

Dans ce lien SO, il y a quelques réponses, mais il y a 6 ans.

Je sais que c'est une meilleure pratique d'écrire votre nom et votre date, puis de commencer à créer la procédure, mais je ne vois pas où je travaille.

S'il n'y a aucun moyen de le faire, cette tâche peut-elle être effectuée avec des déclencheurs?

Et une question bonus. Est-ce le travail d'un dba? savoir qui l'a créé?

Merci beaucoup.

Racer SQL
la source

Réponses:

7

Oui, il y a un moyen

La table pour stocker les résultats du déclencheur

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

Le déclencheur

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 requête pour auditer les résultats du déclencheur

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 autre administrateur de base de données peut avoir une opinion différente, mais je considère que la disponibilité de ces informations est importante pour un administrateur de base de données.

Craig Efrein
la source
Bonjour. Merci pour la réponse rapide. Je vais faire un petit test ici.
Racer SQL
@craig ... J'ai des problèmes ici FROM [SOME_DATABASE].[dbo].[ddl_objects_log]... Dois-je créer la table?
Racer SQL
Cela est possible s'il existe un déclencheur existant qui l'enregistrera. La trace par défaut (sauf si vous l'avez explicitement désactivée) est déjà en cours d'exécution et capture les événements (sauf si elle est survolée et que les informations ont disparu).
Kin Shah
@RafaelPiccinelli J'ai ajouté le code SQL de la table
Craig Efrein
Merci @CraigEfrein ... @ kin, j'ai "trace par défaut activée = 1". Je n'ai pas compris votre commentaire. Ce déclencheur ne fonctionnera que si j'ai déjà un autre déclencheur? Désolé, je suis nouveau dans le monde de la sécurité.
Racer SQL
3

Si la trace par défaut est activée et qu'elle n'a pas survolé, vous pouvez l'utiliser pour trouver qui a créé le 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 ;

Cliquer ici pour agrandir

entrez la description de l'image ici

Est-ce le travail d'un dba? pour savoir qui a créé quoi à l'intérieur du sql?

Cela dépend de la raison pour laquelle vous voulez savoir si des objets sont créés / modifiés ou supprimés. Vous pouvez utiliser la notification d'événements pour vous connecter et vous informer si vous pensez que des objets sont créés / déposés ou modifiés par un utilisateur non autorisé. Assurez-vous que les filtres appropriés sont en place.

entrez la description de l'image ici

Pour l'exhaustivité de cette réponse, je veux mentionner - Quelles informations sur les événements puis-je obtenir par défaut de SQL Server? d'Aaron Bertrand.

Kin Shah
la source
bonjour @kin. J'ai des problèmes avec la "conversion". Mais qu'est-ce qui ne va pas? Il indique une erreur sintax.
Racer SQL
@RafaelPiccinelli quelle ligne vous obtenez une erreur? Je l'ai essayé et je n'ai pas d'erreur. Vous devez également modifier DATEADD(HH, -24, GETDATE())si vous souhaitez obtenir des résultats pendant plus de 24 heures.
Kin Shah
désolé, je ne sais pas ce qui n'allait pas. Je viens de copier / coller à nouveau et son fonctionnement. Si je commente cette ligne, puis-je obtenir toutes les procédures d'une certaine base de données, en utilisant `AND DatabaseID = 224` par exemple?
Racer SQL
@RafaelPiccinelli Heureux que cela fonctionne. Si vous commentez cette ligne (qui est un filtre), vous obtiendrez tous les résultats. Jouez simplement avec les filtres pour obtenir les résultats souhaités - filtrez par dbid / dbname ou même par nom SP. Cela ne vous donnera pas l'utilisateur qui a créé le SP, mais vous donnera le temps quand un SP a été créé -select * from sys.procedures where type = 'P' order by create_date desc
Kin Shah
Merci @Kin, je l'utilise en ce moment. Je ne veux vraiment pas être ennuyeux, mais pourquoi ne reçois-je que les résultats d'une seule base de données? J'utilise la requête publiée ici (la grande) mais je ne vois qu'une seule base de données. Si j'utilise AND DatabaseID= 'the_Database_I_Want, ça ne me montre rien, même avec des DATEADD(HH, -24, GETDATE())commentaires. Est-ce que je fais quelque chose de mal?
Racer SQL
3

J'arrive tard, mais je "fais" des choses de sécurité et * d'administration.

Est-ce le travail d'un dba? pour savoir qui a créé quoi à l'intérieur du sql?

OUI . Il est important d'avoir ou de créer ces journaux dans la mesure du possible. Cependant, il est également de votre responsabilité, à mon avis, de ne pas "ouvrir cette boîte" jusqu'à ce qu'elle devienne importante. En d'autres termes - encore une fois, à mon avis - c'est votre travail de fournir le référentiel pour les données, assurez-vous qu'il est sécurisé, assurez-vous qu'il est réglé ... puis restez à l'écart des données à l'intérieur, sauf si vous êtes appelé spécifiquement regardez-le ou à moins qu'il ne soit nécessaire pour atteindre votre objectif.

Mon opinion et mon point de vue, mais je traite des données sensibles et confidentielles depuis de nombreuses années et je me suis fait un devoir de ne presque jamais «ouvrir la boîte», car cela dégrade la confiance des utilisateurs.

Permettez-moi maintenant de prendre un chemin différent : que se passe-t-il si personne ne peut rapidement comprendre comment la procédure répond aux cas marginaux? Ce qui pourrait vous prendre, moi ou moi, une heure à réfléchir peut prendre quelques minutes à l'auteur: "ah, c'est vrai, cette chose échoue quand ..."

  1. Il y avait une et une seule exception. En 2007 environ, j'ai remarqué une tonne d'activité réseau sur le segment. Je l'ai lâché pendant une journée, puis j'ai enquêté, car il provenait de la machine d'une personne qui semblait être plus éloignée du bureau. Le jour en question, elle était partie pendant la moitié de la journée, donc ma main a été forcée . Il s'avère qu'elle téléchargeait des CD de Limewire et de Bearshare pour son prochain mariage. Je l'ai remis à son patron pour discussion. Il a décidé de ne rien faire, mais j'ai pensé qu'il devrait au moins le savoir, car cela risquait d'entraîner une action en justice.
Chris
la source