Gerador de Senhas

Esse é um código antigo que estava escondido no HD.

Bem simples e usual.

/*
Versao: 1.0
Data: 20100302
Por: Ricardo Leka
Site: http://leka.com.br
email: ricardo@leka.com.br
twitter: @bigleka
*/
/*
Gerador de Senhas
Pode gerar senhas com quantidades minima e maxima de caracteres
com numeros ou complexidade
*/
DECLARE
  @complex tinyint
  , @minlen tinyint
  , @maxlen tinyint  

SET @minlen = 4 --tamanho minimo da senha
SET @maxlen = 8 --tamanho maximo da senha
SET @complex = 4
-- 1 todas as letras minusculas
-- 2 inclui letras maiusculas
-- 3 inclui numeos
-- 4 inclui caracteres especiais

DECLARE
  @password varchar(12)
  , @len tinyint
  , @type  tinyint
  , @type2 tinyint

SET @len = 0
SET @password = ''
WHILE @len NOT BETWEEN @minlen and @maxlen
  BEGIN
    SET @len = ROUND(1 + (RAND(CHECKSUM(NEWID())) * @maxlen), 0) + 1
  END
WHILE @len > 0
  BEGIN
    DECLARE @newchar CHAR(1)
    SET @type = ROUND(1 + (RAND(CHECKSUM(NEWID())) * (@complex - 1)), 0)
    IF @type = 1
      SET @newchar = CHAR(ROUND(97 + (RAND(CHECKSUM(NEWID())) * 25), 0))
    IF @type = 2
      SET @newchar = CHAR(ROUND(65 + (RAND(CHECKSUM(NEWID())) * 25), 0))
    IF @type = 3
      SET @newchar = CHAR(ROUND(48 + (RAND(CHECKSUM(NEWID())) * 9), 0))
    IF @type = 4
      BEGIN
        SET @type2 = ROUND(1 + (RAND(CHECKSUM(NEWID())) * 3), 0)
        IF @type2 = 1
          SET @newchar = CHAR(ROUND(33 + (RAND(CHECKSUM(NEWID())) * 14), 0))
        IF @type2 = 2
          SET @newchar = CHAR(ROUND(58 + (RAND(CHECKSUM(NEWID())) * 6), 0))
        IF @type2 = 3
          SET @newchar = CHAR(ROUND(91 + (RAND(CHECKSUM(NEWID())) * 5), 0))
        IF @type2 = 4
          SET @newchar = CHAR(ROUND(123 + (RAND(CHECKSUM(NEWID())) * 3), 0))
      END
-- remove caracteres que podem ser confundidos com outros
    IF @newchar NOT IN ('b', 'l', 'o', 's', 'I', 'O', 'S', '0', '1', '!', '''', '.', ',', '/', '`', '\', '|')
      BEGIN
        SET @password = @password + @newchar
        SET @len = @len - 1
      END
  END
SELECT @password as Senha

1807

Atualmente meu notebook (também conhecido como desktop porque a bateria já era) não tem muita capacidade de suportar alguns testes,,, (Acer Aspire 5050 – AMD Turion 1 core, 1.9GB RAM, 35GB HD),,,

Então tentei fazer uma coisa interessante,,,, criar um banco e apontar os arquivos para meu storage (QNAP TS-110),,,

Tenho 2 instâncias de SQL instaladas nesse note, 1 SQL Server 2008 R2 e 1 SQL Server 2005.

Claro que no 2008 R2 funcionou e no 2005 não…

yep2008

nop

Ai lembrei que para o SQL 2005 (e para o 2008 sem ser R2) criar uma base em local UNC eu precisava habilitar a trace flag 1807. Feito isso conseguir criar a base sem problema.

yep

Achei interessante relembrar isso, pois vai que uma hora qualquer alguém precisa, ou para fazer um LAB ou por falta de espaço (meu caso) você sempre tem uma alternativa… e muita gente nem lembra dessa possibilidade…

T-SQL Tuesday #21 – Depois arrumo esse código,,,

Dessa vez o anfitrião do T-SQL Tuesday é o próprio idealizador Adam Machanic (Blog | Twitter).

E de uma forma diferente, não é na Terça-feira,,, por quê?

Porque não importa, desde que funcione pode ser zuado mesmo,,, o tópico desse mês é sobre “mostrar seu código lixo para o mundo”,,,

Todo mundo já escreveu um código uma vez ou outra,,,, todo o DBA tem aquele conjunto de scripts que o ajudam a identificar alguns problemas, fazer um tunning, arrumar alguma coisa,,, E com certeza todo mundo tem aquele código que hoje, pega para olha e começa a dar risada de como é que teve coragem de fazer uma coisa como aquela…

Meu exemplo é bem simples, O código é horrível, demora demais mas, funciona,,,

Ele troca os dados de posição de uma coluna específica.

WITH cteTableTel AS (
    SELECT
        ROW_NUMBER() OVER (ORDER BY NEWID()) AS n,
        SOBRENOME
    FROM CLIENTES
    )
UPDATE CLIENTES
   SET ENDERECO = (
       SELECT ENDERECO
       FROM cteTableTel
       WHERE cteTableTel.n = CLIENTES.ID)
Esse código funciona, não é nada bonito, não é performático, mas para a necessidade de uma base de treino com dados reais ele ajuda bastante,,,
Se você percebeu ele tem um problema,,, sabe qual é?
Como você garante que todas as linhas da tabela de clientes realmente estão em uma sequencia? Você pode ter apagado algum registro uma hora ou outra,,, Logo, haverá cliente que o endereço não vai ser atualizado,,
Já sei, você nem reparou nesse problema,,, você deve estar pensando: “por que ele esta fazendo um update na tabela de clientes se ele está usando uma CTE?”, ou também, “Legal, ele está fazendo isso em uma tabela que tem algum tipo de ID e quando tem aquelas tabelas que não da pra usar nada de referencia?”
Como eu disse, ele não é performático, e eu nem tinha me atentado nesses detalhes na época,,,  Houveram duas situações que me refizeram rever esse código: o primeiro caso dos usuários que não tinham os dados alteradores e o último… ai com muita vontade resolvi reescrever,,,
E ele ficou mais ou menos assim:
;WITH cte AS (
    SELECT
        ROW_NUMBER() OVER (ORDER BY NEWID()) AS n1,
        ROW_NUMBER() OVER (order by SOBRENOME) AS n2,
        SOBRENOME
    FROM CLIENTES
    )
UPDATE c1
   SET SOBRENOME = c2.SOBRENOME
   from cte as c1
   inner join cte as c2
   on c1.n1 = c2.n2

Dessa vez não tem problema com o usuário sem o dado alterado, performance melhorada em quase 90% e pouco importa se a tabela em algum registro para referencia,,,

Eu comparei a execução dos 2 códigos em uma tabela com um pouco mais de  3 milhões de linhas e o segundo código demorou quase 4 horas para finalizar,,, já o primeiro código eu parei a execução dele depois de 2 SEMANAS executando.

Tenho códigos piores no meu repositório? claro que sim. Esse é apenas um exemplo de um dos piores que já fiz…

Qual é o seu? tem coragem mostrar?

Procurando por conversão implícita

Assistindo ontem a apresentação do Marcos Freccia (Blog | Twitter) sobre “10 coisas que todo desenvolvedor deveria saber sobre SQL Server” alguém perguntou como ver as conversões implícitas que estão sendo executadas no SQL,,, ou alguma coisa assim,,,

Então, segue um script rapidão que mostra as conversões,,, o chato desse script é que ele tem que ser executado por banco,,,

Vou tentar montar um outro que traga a informação de todos os bancos,,,

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 

DECLARE @dbname SYSNAME
SET @dbname = QUOTENAME(DB_NAME()); 

WITH XMLNAMESPACES
   (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
SELECT
   stmt.value('(@StatementText)[1]', 'varchar(max)'),
   t.value('(ScalarOperator/Identifier/ColumnReference/@Schema)[1]', 'varchar(128)'),
   t.value('(ScalarOperator/Identifier/ColumnReference/@Table)[1]', 'varchar(128)'),
   t.value('(ScalarOperator/Identifier/ColumnReference/@Column)[1]', 'varchar(128)'),
   ic.DATA_TYPE AS ConvertFrom,
   ic.CHARACTER_MAXIMUM_LENGTH AS ConvertFromLength,
   t.value('(@DataType)[1]', 'varchar(128)') AS ConvertTo,
   t.value('(@Length)[1]', 'int') AS ConvertToLength,
   query_plan
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS qp
CROSS APPLY query_plan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS batch(stmt)
CROSS APPLY stmt.nodes('.//Convert[@Implicit="1"]') AS n(t)
JOIN INFORMATION_SCHEMA.COLUMNS AS ic
   ON QUOTENAME(ic.TABLE_SCHEMA) = t.value('(ScalarOperator/Identifier/ColumnReference/@Schema)[1]', 'varchar(128)')
   AND QUOTENAME(ic.TABLE_NAME) = t.value('(ScalarOperator/Identifier/ColumnReference/@Table)[1]', 'varchar(128)')
   AND ic.COLUMN_NAME = t.value('(ScalarOperator/Identifier/ColumnReference/@Column)[1]', 'varchar(128)')
WHERE t.exist('ScalarOperator/Identifier/ColumnReference[@Database=sql:variable("@dbname")][@Schema!="[sys]"]') = 1

Histórico de Backup

Quem faz manutenção do MSDB regularmente? Ou tem algum job agendado para fazer o trabalho, levanta a mão.

\o/ <- não parece mas é um boneco com as duas mãos levantadas,,,

Coloquem o resultado do script abaixo nos comentários e vamos ver quem tem o histórico mais antigo…

select top 1 backup_start_date
from msdb.dbo.backupset with (nolock)
order by backup_set_id asc

A minha versão do Blitz

A algum tempo atras assisti uma apresentação web do Sr. Brent Ozar (Blog | Twitter), onde ele demonstrava um conjunto de scripts para um “levantamento sem intervenção” de um servidor SQL Server.

Achei a ideia muito interessante,,, Como em muitas vezes apenas chegamos em uma empresa e já somos apresentados a um servidor com SQL é interessante saber o que acontece, ou o que ele tem, antes de começar a fazer qualquer coisa. Em outros casos, acontece também de alguém chegar pra você e perguntar alguma coisa de algum servidor que você nunca ouviu falar,,, Sempre vem acompanhado daquela história triste do consultor que veio fazer a instalação disse que precisava de um banco, ai alguém subiu uma maquina (quando não coloca na mesma maquina) e que agora está dando problema e eles não dão suporte,,,, ai sobra pra quem???? adivinha ?!?!?!?

Eu fiz algumas alterações no que achei mais interessante, mas o script original você pode achar no site do Brent Ozar.

/*
Versao: 0.5
Data:    20110523
Por:    Ricardo Leka
Site:   
http://leka.com.br
email:    ricardo@leka.com.br
*/
/*
Versao do SQL
Traz informacoes interessante sobre o nome da maquina, se tem instancia, versao de produto,
SP, collation da instancia, se esta ou nao em cluster
*/

Print ‘Versao de SQL’

SELECT
CAST( SERVERPROPERTY( ‘MachineName’ ) AS varchar( 30 ) ) AS MachineName ,
CAST( SERVERPROPERTY( ‘InstanceName’ ) AS varchar( 30 ) ) AS Instance ,
CAST( SERVERPROPERTY( ‘ProductVersion’ ) AS varchar( 30 ) ) AS ProductVersion ,
CAST( SERVERPROPERTY( ‘ProductLevel’ ) AS varchar( 30 ) ) AS ProductLevel ,
CAST( SERVERPROPERTY( ‘Edition’ ) AS varchar( 30 ) ) AS Edition ,
( CASE SERVERPROPERTY( ‘EngineEdition’)
WHEN 1 THEN ‘Personal or Desktop’
WHEN 2 THEN ‘Standard’
WHEN 3 THEN ‘Enterprise’
END ) AS EngineType ,
CAST( SERVERPROPERTY( ‘LicenseType’ ) AS varchar( 30 ) ) AS LicenseType ,
SERVERPROPERTY( ‘NumLicenses’ ) AS #Licenses,
sERVERPROPERTY(‘Collation’) AS Collation,
( CASE SERVERPROPERTY( ‘IsClustered’)
WHEN 0 THEN ‘Nao’
WHEN 1 THEN ‘Sim’
END ) AS Cluster;

SELECT @@VERSION AS [SQL Server Details];

/*
Pega algumas informacoes interessantes como
nome, owner, data de criação, dbid, Modo de Compatiblidade das bases, recovery model,  versao e status

ATENCAO: Lembre-se que a ideia do script eh de apenas ver o que tem,
caso encontre alguma base com status diferente de online ele nao faz nada
e na teoria ainda nao eh a hora de voce fazer. Apenas reporte.
*/

Print ‘Nome, owner, dbcreate, dbid, cmptlvl, recovery, version, status’

select    name as [NAME]
        ,suser_sname(sid) as [Owner]
        ,convert(nvarchar(11), crdate) as [Data Criacao]
        ,dbid as [DBID]
        ,cmptlevel
        ,databasepropertyex(name, ‘recovery’)
        ,version
        ,databasepropertyex(name, ‘status’)
from master.dbo.sysdatabases

/*
Backup FULL

Uma das informacoes mais importantes, tem backup?
*/

Print ‘Backup FULL’

SELECT d.name, MAX(b.backup_finish_date) AS last_backup_finish_date
FROM master.sys.databases d
LEFT OUTER JOIN msdb.dbo.backupset b ON d.name = b.database_name AND b.type = ‘D’
WHERE d.database_id NOT IN (2, 3)
GROUP BY d.name
ORDER BY 2 DESC

/*
Backup LOG

Outra informacao muito importante,,,,
*/

Print ‘Backup Log’

SELECT d.name, d.recovery_model, d.recovery_model_desc
FROM master.sys.databases d
LEFT OUTER JOIN msdb.dbo.backupset b ON d.name = b.database_name AND b.type = ‘L’
WHERE d.recovery_model IN (1, 2) AND b.type IS NULL AND d.database_id NOT IN (2, 3)

/*
Localizacao dos backups

Se houve backup, pra onde ele foi?
*/

Print ‘Localizacao dos Backups’

SELECT TOP 100 physical_drive, physical_name, *
FROM msdb.dbo.backupfile
ORDER BY 1 DESC

/*
A quanto tempo existe historico de backup?

No SQL 2k, havia um grande problema de performance quando o historico ficava muito grande.
*/

Print ‘Backup History’

SELECT TOP 1 backup_start_date
FROM msdb.dbo.backupset WITH (NOLOCK)
ORDER BY backup_set_id ASC

/*
Quando foi que o DBCC CHECKDB rodou pela última vez?

Isso eh tao bom quando retorna alguma coisa,,,
*/

Print ‘DBCC CHECKDB’

CREATE TABLE #temp (         
       ParentObject     VARCHAR(255)
       , [Object]       VARCHAR(255)
       , Field          VARCHAR(255)
       , [Value]        VARCHAR(255)  
   )  
  
CREATE TABLE #DBCCResults (
        ServerName           VARCHAR(255)
        , DBName             VARCHAR(255)
        , LastCleanDBCCDate  DATETIME  
    )  
   
EXEC master.dbo.sp_MSforeachdb      
           @command1 = ‘USE ? INSERT INTO #temp EXECUTE (”DBCC DBINFO WITH TABLERESULTS”)’
           , @command2 = ‘INSERT INTO #DBCCResults SELECT @@SERVERNAME, ”?”, Value FROM #temp WHERE Field = ”dbi_dbccLastKnownGood”’
           , @command3 = ‘TRUNCATE TABLE #temp’  
  
   –Delete duplicates due to a bug in SQL Server 2008
  
   ;WITH DBCC_CTE AS
   (
       SELECT ROW_NUMBER() OVER (PARTITION BY ServerName, DBName, LastCleanDBCCDate ORDER BY LastCleanDBCCDate) RowID
       FROM #DBCCResults
   )
   DELETE FROM DBCC_CTE WHERE RowID > 1;
  
    SELECT       
           ServerName      
           , DBName      
           , CASE LastCleanDBCCDate
                   WHEN ’1900-01-01 00:00:00.000′ THEN ‘Never ran DBCC CHECKDB’
                   ELSE CAST(LastCleanDBCCDate AS VARCHAR) END AS LastCleanDBCCDate   
   FROM #DBCCResults  
   ORDER BY 3
  
   DROP TABLE #temp, #DBCCResults;

/*
Quem faz parte do sysadmin ou securityadmin

Quantas outras pessoas podem acessar o SQL e fazer algum tipo de estrago?
*/

SELECT    l.name
        ,l.denylogin
        ,l.isntname
        ,l.isntgroup
        ,l.isntuser
FROM master.dbo.syslogins l
WHERE l.sysadmin = 1 OR l.securityadmin = 1
ORDER BY l.isntgroup, l.isntname, l.isntuser

/*
Configurações da instância

Isso mostra como esta configurado hoje, e nao como estava configurado…
*/
EXEC dbo.sp_configure ‘show advanced options’, 1
GO
RECONFIGURE
GO
EXEC dbo.sp_configure

/*
Email

O SQL envia email?
*/

Print ‘Email’

EXEC msdb.dbo.sp_send_dbmail
    @recipients = ‘ricardo@leka.com.br’,
    @body = @@SERVERNAME,
    @subject = ‘Testando SQL Server Database Mail – veja no corpo o nome do servidor’;
GO

/*
Configurando o sistema de email para enviar mensagem de erros

Aqui vai alguma configuracao,,, nada critica,,,
*/

Print ‘Configurando o sistema de emails’

USE [msdb]
GO
EXEC msdb.dbo.sp_add_operator @name=N’The Database Administrator’,
        @enabled=1,
        @weekday_pager_start_time=0,
        @weekday_pager_end_time=235959,
        @saturday_pager_start_time=0,
        @saturday_pager_end_time=235959,
        @sunday_pager_start_time=0,
        @sunday_pager_end_time=235959,
        @pager_days=127,
        @email_address=N’suporte@asd.com’,
        @pager_address=N’0119999999@operadora.com.br’,
        @category_name=N’[Uncategorized]‘
GO
EXEC msdb.dbo.sp_add_alert @name=N’Severity 016′,
        @message_id=0,
        @severity=16,
        @enabled=1,
        @delay_between_responses=60,
        @include_event_description_in=1,
        @job_id=N’00000000-0000-0000-0000-000000000000′
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N’Severity 016′, @operator_name=N’The Database Administrator’, @notification_method = 7
GO
EXEC msdb.dbo.sp_add_alert @name=N’Severity 017′,
        @message_id=0,
        @severity=17,
        @enabled=1,
        @delay_between_responses=60,
        @include_event_description_in=1,
        @job_id=N’00000000-0000-0000-0000-000000000000′
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N’Severity 017′, @operator_name=N’The Database Administrator’, @notification_method = 7
GO
EXEC msdb.dbo.sp_add_alert @name=N’Severity 018′,
        @message_id=0,
        @severity=18,
        @enabled=1,
        @delay_between_responses=60,
        @include_event_description_in=1,
        @job_id=N’00000000-0000-0000-0000-000000000000′
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N’Severity 018′, @operator_name=N’The Database Administrator’, @notification_method = 7
GO
EXEC msdb.dbo.sp_add_alert @name=N’Severity 019′,
        @message_id=0,
        @severity=19,
        @enabled=1,
        @delay_between_responses=60,
        @include_event_description_in=1,
        @job_id=N’00000000-0000-0000-0000-000000000000′
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N’Severity 019′, @operator_name=N’The Database Administrator’, @notification_method = 7
GO
EXEC msdb.dbo.sp_add_alert @name=N’Severity 020′,
        @message_id=0,
        @severity=20,
        @enabled=1,
        @delay_between_responses=60,
        @include_event_description_in=1,
        @job_id=N’00000000-0000-0000-0000-000000000000′
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N’Severity 020′, @operator_name=N’The Database Administrator’, @notification_method = 7
GO
EXEC msdb.dbo.sp_add_alert @name=N’Severity 021′,
        @message_id=0,
        @severity=21,
        @enabled=1,
        @delay_between_responses=60,
        @include_event_description_in=1,
        @job_id=N’00000000-0000-0000-0000-000000000000′
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N’Severity 021′, @operator_name=N’The Database Administrator’, @notification_method = 7
GO
EXEC msdb.dbo.sp_add_alert @name=N’Severity 022′,
        @message_id=0,
        @severity=22,
        @enabled=1,
        @delay_between_responses=60,
        @include_event_description_in=1,
        @job_id=N’00000000-0000-0000-0000-000000000000′
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N’Severity 022′, @operator_name=N’The Database Administrator’, @notification_method = 7
GO
EXEC msdb.dbo.sp_add_alert @name=N’Severity 023′,
        @message_id=0,
        @severity=23,
        @enabled=1,
        @delay_between_responses=60,
        @include_event_description_in=1,
        @job_id=N’00000000-0000-0000-0000-000000000000′
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N’Severity 023′, @operator_name=N’The Database Administrator’, @notification_method = 7
GO
EXEC msdb.dbo.sp_add_alert @name=N’Severity 024′,
        @message_id=0,
        @severity=24,
        @enabled=1,
        @delay_between_responses=60,
        @include_event_description_in=1,
        @job_id=N’00000000-0000-0000-0000-000000000000′
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N’Severity 024′, @operator_name=N’The Database Administrator’, @notification_method = 7
GO
EXEC msdb.dbo.sp_add_alert @name=N’Severity 025′,
        @message_id=0,
        @severity=25,
        @enabled=1,
        @delay_between_responses=60,
        @include_event_description_in=1,
        @job_id=N’00000000-0000-0000-0000-000000000000′
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N’Severity 025′, @operator_name=N’The Database Administrator’, @notification_method = 7
GO

/*
Objetos em bases de sistema

Coisas que nao deveriam estar neste lugar
*/

Print ‘Coisas no lugar errado’

SELECT * FROM master.sys.tables WHERE name NOT IN (‘spt_fallback_db’, ‘spt_fallback_dev’, ‘spt_fallback_usg’, ‘spt_monitor’, ‘spt_values’, ‘MSreplication_options’)
SELECT * FROM master.sys.procedures WHERE name NOT IN (‘sp_MSrepl_startup’, ‘sp_MScleanupmergepublisher’)
SELECT * FROM model.sys.tables
SELECT * FROM model.sys.procedures

/*
Start up Stored procedure

Achou alguma procedure aqui? estranho,,, veja o que ela faz,,,
pode ser o mau esperando um boot,,,
*/

SELECT *
FROM master.INFORMATION_SCHEMA.ROUTINES
WHERE OBJECTPROPERTY(OBJECT_ID(ROUTINE_NAME),’ExecIsStartup’) = 1

/*
Quem mais existe em server-level
*/

SELECT * FROM sysservers

/*
Agora mais informacoes sobre as bases

classico,,, nada fora do comum,,,
*/

SELECT * FROM sysdatabases

/*
Onde estao os arquivos

onde eles estao? quantos sao?
*/

CREATE TABLE #DatabaseFiles(
    [database_name] [sysname] NOT NULL,
    [file_id] [int] NOT NULL,
    [file_guid] [smallint] NULL,
    [size] [int] NOT NULL,
    [max_size] [int] NOT NULL,
    [growth] [int] NOT NULL,
    [status] [int] NULL,
    [perf] [int] NOT NULL,
    [name] [sysname] NOT NULL,
    [physical_name] [nvarchar](260) NOT NULL,
)
EXEC dbo.sp_MSforeachdb ‘INSERT INTO #DatabaseFiles SELECT ”[?]” AS database_name, * FROM [?].dbo.sysfiles’
SELECT * FROM #DatabaseFiles ORDER BY database_name
DROP TABLE #DatabaseFiles

/*
Triggers

isso pode demorar um pouco,,,
e mais ainda pra ler,,,,
*/

Print ‘Triggers’

EXEC dbo.sp_MSforeachdb ‘SELECT ”[?]” AS database_name, o.name AS table_name, t.* FROM [?].sys.triggers t INNER JOIN [?].sys.objects o ON t.parent_id = o.object_id’

/*
Alguns Waits

Nao zere o contador, apenas veja o que tem,,,
*/

Print ‘Alguns Waits’

SELECT *, (wait_time_ms – signal_wait_time_ms) AS real_wait_time_ms
FROM sys.dm_os_wait_stats
ORDER BY (wait_time_ms – signal_wait_time_ms) DESC

/*
Frangmentacao de indices

se voce achou que o de Triggers demorou,,, imagina esse,,,,
*/

Print ‘Fragmentacao de indices’

SELECT
      db.name AS databaseName
    , ps.OBJECT_ID AS objectID
    , ps.index_id AS indexID
    , ps.partition_number AS partitionNumber
    , ps.avg_fragmentation_in_percent AS fragmentation
    , ps.page_count
FROM sys.databases db
  INNER JOIN sys.dm_db_index_physical_stats (NULL, NULL, NULL , NULL, N’Limited’) ps
      ON db.database_id = ps.database_id
WHERE ps.index_id > 0
   AND ps.page_count > 100
   AND ps.avg_fragmentation_in_percent > 30
OPTION (MaxDop 1);

/*
Jobs

Simples,,, quais sao, a quem pertence e se estao ativos,,,
NAO tente corrigir-los agora,,, entenda o que eles fazem ou deveriam fazer,,,
*/

Print ‘Jobs’

select     Name as [Name]
    ,SUSER_SNAME(owner_sid) as [Owner]
    ,(    Case enabled
        WHEN 0 THEN ‘Nao’
        WHEN 1 THEN ‘Sim’
        END
    ) AS [Enable]
    , description as [Description]
from msdb.dbo.sysjobs_view
order by name

/*
Users

Quais sao os usuarios de Windows e os de SQL
Preste atencao quais sao os usuarios, podem tem mais do que precisa,,,,
*/

Print ‘Usuarios windows e SQL’

select     Name as [Name]
    ,(    Case isntname
        WHEN 0 THEN ‘SQL Server Standard’
        WHEN 1 THEN ‘Windows Authentication’
        END
    ) AS [Type]
from master.sys.syslogins

/*
Usuarios x Bases

Esse aqui nao deve demorar muito,,,
apenas gera um relacionamento dos usuarios que estao nas bases
compare com a quantidade de usuarios que voce pegou na lista acima
*/

Print ‘Usuarios por Bases’

create table #UsrDataMapping(
[database_name] [sysname] NULL,
[name] [sysname] NULL,
[schema] [sysname] NULL
)
EXEC sp_MSforeachdb ‘insert into #UsrDataMapping SELECT ”?” as DBNAME,
–u.name AS [Name],
SUSER_SNAME(sid) AS [Name],
ISNULL(u.default_schema_name,N””) AS [DefaultSchema]
FROM
[?].sys.database_principals AS u
LEFT OUTER JOIN [?].sys.database_permissions AS dp ON dp.grantee_principal_id = u.principal_id
WHERE
(u.type in (”U”, ”S”, ”G”, ”C”, ”K”))
and dp.state = ”G”

select * from #UsrDataMapping order by database_name
drop table #UsrDataMapping

(update 28/09/2011) ATUALIZAÇÃO !!!

Pessoal, desculpe ter colocado o código sem uma formatação de cores, mas o plug-in do Microsoft Live Write é muito ruim,,, e ele quebra todo o código…

O arquivo com o script está no SkyDrive.

Quando foi que trocaram a senha?

Quando estamos no SQL Server (2005 ou superior), existem uma função que mostra algumas propriedades interessante sobre o login do SQL chamada LoginProperty.

Não conheço muitas aplicações que possuem interface que permite o usuário trocar a senha dele no SQL,,, mas achei interessante ter essa opção para saber quando alguém trocou a senha e “esqueceu” de avisar,,, ai tem aplicação que não abre,,, usuário que não loga,,, e quase sempre ninguém nunca fez nada….

Aqui vão alguns selects interessantes….

Mostra todos os logins que tiveram a senha trocada a mais de 30 dias:

 1: SELECT name, LOGINPROPERTY([name], 'PasswordLastSetTime') AS 'SenhaTrocada'
 2: FROM sys.sql_logins
 3: WHERE LOGINPROPERTY([name], 'PasswordLastSetTime') < DATEADD(dd, -60, GETDATE());

Mostra todos os logins que tiveram a senha trocada no último dia:

 1: SELECT name, LOGINPROPERTY([name], 'PasswordLastSetTime') AS 'SenhaTrocada'
 2: FROM sys.sql_logins
 3: WHERE LOGINPROPERTY([name], 'PasswordLastSetTime') > DATEADD(dd, -1, GETDATE());

T-SQL Tuesday #17–Apply

O tópico deste mês para o T-SQL Tuesday é o operador apply,,,

Caso você não faça ideia de pra que serve o apply leia aqui.

Para este post vou coloca um script simples usando o apply.

Ele não faz nada muito importante, apenas mostra as 20 querys que mais gerão stress de disco:

SELECT TOP 20 SUBSTRING(qt.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset
END – qs.statement_start_offset)/2)+1),
qs.execution_count,
qs.total_logical_reads, qs.last_logical_reads,
qs.min_logical_reads, qs.max_logical_reads,
qs.total_elapsed_time, qs.last_elapsed_time,
qs.min_elapsed_time, qs.max_elapsed_time,
qs.last_execution_time,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qt.encrypted=0
ORDER BY qs.total_logical_reads DESC

Sou alguém importante no SQL?

Algumas vezes acontece de você prestar serviço para alguma empresa/usuário/amigo e o pessoal cria um usuário para acesso ao ambiente SQL, como em muitos casos não precisamos de acesso direto no servidor podemos usar o SSMS/Enterprise Manager ou qualquer outra ferramenta que esteja disponível. Apenas precisamos saber qual o nível de acesso do nosso usuário…

Continue lendo

T-SQL Tuesday #016 – Blocking Processes – #tsql2sday

O T-SQL Tuesday desse mês é sobre Aggregate Functions,,,

O código abaixo é bem simples, ele vai exibir algum block que pode estar ocorrendo no SQL nada muito complicado mas é interessante de ter,,,

 1: SET NOCOUNT ON
 2: 
 3: SELECT  a.spid AS "Block" ,
 4:         ( SELECT    COUNT(*)
 5:           FROM      master.dbo.sysprocesses b
 6:           WHERE     b.blocked = a.spid
 7:         ) AS "BlockCount" ,
 8:         ( SELECT    MAX(waittime)
 9:           FROM      master.dbo.sysprocesses b
 10:           WHERE     b.blocked = a.spid
 11:         ) AS "BlockTime" ,
 12:         a.status ,
 13:         a.program_name ,
 14:         a.cmd ,
 15:         a.last_batch
 16: FROM    master.dbo.sysprocesses a
 17: WHERE   a.spid IN ( SELECT  blocked
 18:                     FROM    master.dbo.sysprocesses
 19:                     WHERE   blocked <> 0 )
 20: ORDER BY a.blocked ASC ,
 21:         BlockCount DESC