¿Quién creó un procedimiento? (SQL Server 2008 R2)

10

¿Hay alguna forma de enumerar quién creó cierta adquisición en SQL Server 2008?

En este enlace SO hay algunas respuestas, pero de hace 6 años.

Sé que es una buena práctica escribir su nombre y fecha, y luego comenzar a crear el procedimiento, pero no veo esto donde trabajo.

Si no hay forma de hacer esto, ¿se puede hacer esta tarea con disparadores?

Y una pregunta extra. ¿Es este el trabajo de un dba? saber quién lo creó?

Muchas gracias.

Racer SQL
fuente

Respuestas:

7

Sí, hay una manera

La tabla para almacenar los resultados del desencadenante

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

El gatillo

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 consulta para auditar los resultados del desencadenante

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

Otro DBA podría tener una opinión diferente, pero considero que tener esta información disponible es importante para un DBA.

Craig Efrein
fuente
Hola. Gracias por la rápida respuesta. Haré una pequeña prueba aquí.
Racer SQL
@craig ... Tengo problemas aquí FROM [SOME_DATABASE].[dbo].[ddl_objects_log]... ¿Debo crear la tabla?
Racer SQL
Esto es posible si hay un activador existente que lo grabará. El seguimiento predeterminado (a menos que lo haya deshabilitado explícitamente) ya se está ejecutando y captura los eventos (a menos que se revierta y la información desaparezca).
Kin Shah
@RafaelPiccinelli Agregué el código SQL de la tabla
Craig Efrein, el
Gracias @CraigEfrein ... @ kin, tengo "rastreo predeterminado habilitado = 1". No entendí tu comentario. ¿Este disparador solo funcionará si ya tengo otro disparador? Lo siento, soy nuevo en el mundo de la seguridad.
Racer SQL
3

Si tiene habilitado el rastreo predeterminado y no se ha reiniciado, puede usarlo para encontrar quién creó el 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 ;

Click aquí para ampliar

ingrese la descripción de la imagen aquí

¿Es este el trabajo de un dba? saber quién creó qué dentro del sql?

Depende de por qué quiere saber si los objetos se crean / alteran o descartan. Puede usar la notificación de eventos para iniciar sesión y notificarle si siente que un usuario no autorizado crea / descarta o altera objetos. Asegúrese de tener los filtros adecuados en su lugar.

ingrese la descripción de la imagen aquí

Para completar esta respuesta, quiero mencionar: ¿Qué información de evento puedo obtener de manera predeterminada de SQL Server? de Aaron Bertrand.

Kin Shah
fuente
hola @kin. Tengo un problema en la "conversión". ¿Pero qué hay de malo allí? Dice error sintax.
Racer SQL
@RafaelPiccinelli ¿en qué línea está recibiendo un error? Lo probé y no recibo ningún error. También debe modificar DATEADD(HH, -24, GETDATE())si desea obtener resultados durante más de 24 horas.
Kin Shah
lo siento, no sé qué estuvo mal. Acabo de copiar / pegar de nuevo y está funcionando. Si comento esta línea, ¿puedo obtener todos los procedimientos de una determinada base de datos, usando `AND DatabaseID = 224` por ejemplo?
Racer SQL
@RafaelPiccinelli Me alegro de que esté funcionando. Si comenta esa línea (que es un filtro), obtendrá todos los resultados. Simplemente juegue con los filtros para obtener los resultados deseados: filtre por dbid / dbname o incluso SP name. Esto no le dará al usuario que creó el SP, pero le dará tiempo cuando se creó un SP -select * from sys.procedures where type = 'P' order by create_date desc
Kin Shah
Gracias @Kin, lo estoy usando en este momento. Realmente no quiero ser molesto, pero ¿por qué obtengo solo los resultados de 1 base de datos? Estoy usando la consulta publicada aquí (la grande) pero solo veo una base de datos. Si lo uso AND DatabaseID= 'the_Database_I_Want, no me muestra nada, incluso con DATEADD(HH, -24, GETDATE())comentarios. ¿Estoy haciendo algo mal?
Racer SQL
3

Llego tarde, pero "hago" cosas de seguridad y administración.

¿Es este el trabajo de un dba? saber quién creó qué dentro del sql?

. Es importante tener o crear estos registros siempre que sea posible. Sin embargo, también es su responsabilidad, en mi opinión, no "abrir este cuadro" hasta que sea importante. En otras palabras, una vez más, en mi opinión, es su trabajo proporcionar el repositorio de datos, asegurarse de que sea seguro, asegurarse de que esté sintonizado ... y luego mantenerse alejado de los datos dentro a menos que se le llame específicamente míralo o a menos que sea necesario para lograr tu objetivo.

Mi opinión y mi punto de vista, pero he tratado con datos confidenciales y confidenciales durante muchos años y me he esforzado por casi nunca "abrir la caja", ya que esto degrada la confianza con los usuarios.

Ahora déjame tomar un camino diferente : ¿qué pasa si nadie puede descubrir rápidamente cómo responde el procedimiento a los casos límite? Lo que podría llevarnos a usted o a mí una hora para reflexionar puede llevar al autor unos minutos: "ah, claro, esto falla cuando ..."

  1. Hubo una y solo una excepción. En 2007 más o menos, noté un montón de actividad de red en el segmento. Lo dejé pasar un día y luego investigué, ya que provenía de la máquina de una persona que parecía estar fuera de la oficina más que dentro. El día en cuestión, ella estuvo ausente la mitad del día, así que me forzaron la mano. . Resulta que estaba descargando CD de Limewire y Bearshare para su próxima boda. Se lo entregué a su jefe para que lo discutiera. Decidió no hacer nada, pero pensé que al menos debería saberlo, ya que ponía a la organización en riesgo de acciones legales.
Chris
fuente