Quem criou um procedimento? (SQL Server 2008 R2)


10

Existe uma maneira de listar quem criou determinadas compras no SQL Server 2008?

Em este link SO existem algumas respostas, mas a partir de 6 anos atrás.

Sei que é uma boa prática escrever seu nome e data e começar a criar o procedimento, mas não vejo isso onde trabalho.

Se não há como fazer isso, essa tarefa pode ser feita com gatilhos?

E uma pergunta bônus. Esse é o trabalho de um dba? saber quem o criou?

Muito obrigado.

Respostas:


7

Sim, há um jeito

A tabela para armazenar os resultados do gatilho

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

O gatilho

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

A consulta para auditar os resultados do acionador

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

Outro DBA pode ter uma opinião diferente, mas considero ter essas informações prontamente disponíveis como importantes para um DBA.


Olá. Obrigado pela resposta rápida. Vou fazer um pequeno teste aqui.
Racer SQL

@ Craig ... Estou tendo problemas aqui FROM [SOME_DATABASE].[dbo].[ddl_objects_log]... Devo criar a tabela?
Racer SQL

Isso é possível se houver um gatilho existente que irá gravá-lo. O rastreio padrão (a menos que você o tenha desativado explicitamente) já está em execução e captura os eventos (a menos que seja rolado e as informações tenham desaparecido).
Kin Shah

@RafaelPiccinelli Adicionei o código SQL da tabela
Craig Efrein 5/15

Obrigado @CraigEfrein ... @ parentes, tenho "rastreio padrão ativado = 1". Não entendi o seu comentário. Esse gatilho só funcionará se eu já tiver outro gatilho? Desculpe, sou um novo no mundo da segurança.
Racer SQL

3

Se você tiver o rastreamento padrão ativado e ele não tiver sido revertido, poderá usá-lo para descobrir quem criou o 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 ;

Clique aqui para ampliar

insira a descrição da imagem aqui

Esse é o trabalho de um dba? saber quem criou o que dentro do sql?

Depende do motivo pelo qual você deseja saber se os objetos são criados / alterados ou descartados. Você pode usar a notificação de eventos para registrar e notificá-lo se sentir que objetos são criados / descartados ou alterados por um usuário não autorizado. Verifique se você possui filtros adequados no local.

insira a descrição da imagem aqui

Para completar esta resposta, quero mencionar - Quais informações do evento posso obter por padrão no SQL Server? de Aaron Bertrand.


olá @kin. Estou com problemas no "convert" .Mas o que há de errado aí? Diz erro de sintaxe.
Racer SQL

@RafaelPiccinelli qual linha você está recebendo um erro? Eu tentei e não recebi nenhum erro. Você também precisa modificar DATEADD(HH, -24, GETDATE())se deseja obter resultados por mais de 24 horas.
Kin Shah

desculpe, eu não sei o que estava errado. Acabei de copiar / colar novamente e está funcionando. Se eu comentar esta linha, posso obter todos os procedimentos de um determinado banco de dados, usando 'AND DatabaseID = 224` por exemplo?
Racer SQL

@RafaelPiccinelli Fico feliz que ele está funcionando. Se você comentar essa linha (que é um filtro), obterá todos os resultados. Basta brincar com os filtros para obter os resultados desejados - filtre por dbid / dbname ou até pelo nome do SP. Isso não vai dar-lhe o usuário que criou o SP, mas vai dar-lhe tempo quando um SP foi criado -select * from sys.procedures where type = 'P' order by create_date desc
Kin Shah

Obrigado @Kin, estou usando agora. Eu realmente não quero ser chato, mas por que estou recebendo apenas os resultados de um banco de dados? Estou usando a consulta postada aqui (a grande), mas vejo apenas um banco de dados. Se eu usar AND DatabaseID= 'the_Database_I_Want, não me mostra nada, mesmo com o DATEADD(HH, -24, GETDATE())comentado. Estou fazendo algo errado?
Racer SQL

3

Estou chegando atrasado, mas "faço" coisas de segurança e administração.

Esse é o trabalho de um dba? saber quem criou o que dentro do sql?

SIM . É importante ter ou criar esses logs sempre que possível. No entanto, também é sua responsabilidade, na minha opinião, não "abrir esta caixa" até que ela se torne importante. Em outras palavras - novamente, na minha opinião - é seu trabalho fornecer o repositório de dados, garantir que eles sejam seguros, garantir que estejam sintonizados ... e depois ficar longe dos dados internos, a menos que você seja chamado especificamente olhe para ele ou a menos que seja necessário para atingir seu objetivo.

Minha opinião e minha visão, mas lidei com dados sensíveis e confidenciais por muitos anos e fiz questão de quase nunca [1] "abrir a caixa", pois isso degrada a confiança dos usuários.

Agora, deixe-me seguir um caminho diferente : e se ninguém puder descobrir rapidamente como o procedimento responde a casos extremos? O que você ou eu levaria uma hora para resolver pode levar alguns minutos para o autor: "ah, certo, isso falha quando ..."

  1. Havia uma e apenas uma exceção. Em 2007, percebi uma tonelada de atividade de rede no segmento. Deixei passar um dia e depois investiguei, pois vinha da máquina de uma pessoa que parecia estar mais fora do escritório do que dentro. No dia em questão, ela ficou fora metade do dia, então minha mão foi forçada . Acontece que ela estava baixando CDs da Limewire e da Bearshare para seu próximo casamento. Eu entreguei para o chefe dela para discussão. Ele decidiu não fazer nada, mas achei que ele deveria pelo menos saber, pois isso colocava a organização em risco de ação legal.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.