Script Challenge – 2017 – O retorno….


Olá bom dia, comunidade e amantes de bancos de dados.

Tudo bem? E ai esta chovendo neste momento na sua cidade? Aqui em São Roque estávamos desde o último dia 12/10/2017 sem chuva, mas nesta última madrugado do dia 25/10 para o dia 26/10 ela retornou com grande força.

Introdução

Você pode estar se perguntando o que o retorno da chuva tem haver com o post desta sessão, na minha opinião tem tudo haver, estou justamente hoje aproveitando a madrugada de trabalho para retornar ao meu blog um das sessões que durante 2 anos me ajudou em muito a manter o número de visitantes em alta.

Se você não conhecia, vai ter a possibilidade de a partir de agora a cada 4 meses por desfrutar da sessão Script Challenge(Script Desafio ou Desafio do Script), pois bem, a melhor forma de traduzir eu deixo para você.

Um pouco de História

Esta é uma sessão criado no final do ano de 2010 e mantida mensalmente até meados de 2012, desde então não me dediquei mais a mesma devido principalmente em não conseguir identificar possíveis scripts dentro da minha biblioteca que poderiam ser apresentados como um scripts considerados como desafio para os profissionais da área de banco de dados.

Mas acredito que nos últimos anos com o crescimento do Microsoft SQL Server, seu nível de evolução, amadurecimento e recursos adicionais, como também, meu nível de experiência profissional e acadêmica também evolui muito, sinto-me preparado para retornar com esta sessão e poder de forma bastante técnica, didática e conceitual poder lançar um “desafio” e responder o mesmo com muito segurança.

Esta é uma sessão que foi criada, pensando em apresentar pequenos blocos de códigos oriundos da linguagem Transact-SQL que possam apresentar um nível de dificuldade e conhecimento técnico um pouco mais elevado, exigindo assim uma análise mais profunda e até mesmo a criação um pequeno cenário de teste para seu entendimento. Vamos então conhecer o bloco de código selecionado para ser o Script Challenge deste post.


Script Challenge – 13

O bloco de código Transact-SQL selecionado para fazer parte do Script Challenge que representa o retorno desta sessão, esta totalmente relacionado com uma tradicional comemoração norte americana realizada no mês de Outubro.

A seguir apresento o bloco de código:


Figura 1 – Short Script 13.

Muito bem, nosso Script Challenge esta apresentado, mas não tudo será como antes.

Gostaria então de destacar duas mudanças iniciais implementadas na sessão Script Challenge a partir deste post:

  1. Como maneira ou forma de dificultar ainda mais o nível de complexidade do código, o bloco de código que representa o Script Challenge selecionado para compor o post será  apresentado no formato de imagem ou figura; e
  2. Algumas partes das linhas de código, trechos, ou partes de código serão omitidas, justamente como forma de tornar este código ainda mais desafiador.

E ai preparado para o desafio? Tenho a certeza que sim!


Sua participação

Legal, agora quero conter com a sua participação, me ajudando a responder este post, outra grande novidade que estou adicionando aos post da sessão Script Challenge será uma pequena enquete com possíveis respostas para identificar qual é a correta relacionada com o desafio apresentado através do bloco de código selecionado para este post, desta forma, apresento a seguir a Enquete – Script Challenge – 13 e suas alternativas de resposta:

Seguindo em frente, já conhecemos o Script Challenge selecionado, sua enquete e relação de opções de resposta, fica faltando somente a sua participação, algo que eu tenho a certeza que vai acontecer rapidamente.

Durante quanto tempo posso participar…

Outra grande mudança na sessão Script Challenge é seu tempo de publicação “validade”, anteriormente os posts desta sessão eram publicados mensalmente ou bimestralmente, agora serão publicados em um período mais longo, ou seja, a cada 4 meses estarei compartilhando com vocês novos posts dedicados exclusivamente para esta sessão.

Desta forma, você terá mais tempo para participar e me ajudar e encontrar a resposta correta para este desafio, enviando suas possíveis sugestões, críticas e até mesmo alternativas de resposta para minha enquete.


Agradecimentos

Obrigado por sua visita, espero que o retorno desta sessão e o conteúdo aqui apresentado como um possível “desafio” possam ser úteis e ao mesmo tempo prover conhecimento, aprendizado ou mostrar recursos e problemas existentes no Microsoft SQL Server que as vezes parecem não ter uma resposta.

Um forte abraço nos encontramos em breve nas demais sessões e especialmente em fevereiro de 2018 em mais um post da sessão Script Challenge.

Sucesso e até mais.

Anúncios

Script Challenge – 12

Dica – Script Challenge – 12


Olá pessoal, bom dia.

Tudo bem? Olha eu aqui outra vez, com mais um Desafio de SQL Server!

O Script Challenge deste mês, com certeza poderá ajudar em muito o seu ambiente na identificação de recursos que possam estar gerando consumo de processamento. Não vou ficar dando dicas ou pistas deste código, quero contar com a sua participação.

A seguir apresentado o Código – Script Challenge – 12:

–Declarando a varavel @Buffers_EmUso

Declare

@Buffers_EmUso Int;

Object_Name=Buffer Manager e Counter_Name=Total Pages*/

 

Select

@Buffers_EmUso = cntr_value From Sys.dm_os_performance_counters

Where

Rtrim(Object_name) LIKE ‘%Buffer Manager’

And

counter_name = ‘Total Pages’;

 

— Declarando a CTE Buffers_Pages para contagem de Buffers por pgina —

 

;With DB_Buffers_Pages AS

(

SELECT database_id, Contagem_Buffers_Por_Pagina  = COUNT_BIG(*)

From Sys.dm_os_buffer_descriptors

Group By database_id

)

 

Select

Case [database_id]

WHEN 32767 Then ‘Recursos de Banco de Dados’ Else DB_NAME([database_id])

End As ‘Banco de Dados’,

Contagem_Buffers_Por_Pagina,

‘Buffers em MBs por Banco’ = Contagem_Buffers_Por_Pagina / 128,

‘Porcentagem de Buffers’ = CONVERT(DECIMAL(6,3), Contagem_Buffers_Por_Pagina * 100.0 / @Buffers_EmUso)

From

DB_Buffers_Pages

Order

By ‘Buffers em MBs por Banco’ Desc;


— Parte 2: —

USE

CRIPTOGRAFIA

GO

 

;WITH DB_Buffers_Pages_Objetos AS

(

Select

SO.name As Objeto,

SO.type_desc As TipoObjeto,

COALESCE(SI.name, ) As Indice,

SI.type_desc As TipoIndice,

p.[object_id],

p.index_id,

AU.allocation_unit_id

From sys.partitions AS P INNER JOIN sys.allocation_units AS AU

ON p.hobt_id = au.container_id

INNER JOIN sys.objects AS SO

ON p.[object_id] = SO.[object_id]

INNER JOIN sys.indexes AS SI

ON SO.[object_id] = SI.[object_id]

AND p.index_id = SI.index_id

Where AU.[type] IN(1,2,3)

And SO.is_ms_shipped = 0

)

 

Select

Db.Objeto, Db.TipoObjeto  As ‘Tipo Objeto’,

Db.Indice,

Db.TipoIndice,

COUNT_BIG(b.page_id) As,

COUNT_BIG(b.page_id) / 128 As

From

DB_Buffers_Pages_Objetos Db INNER JOIN sys.dm_os_buffer_descriptors AS b

ON Db.allocation_unit_id = b.allocation_unit_id

Where

b.database_id = DB_ID()

Group

By Db.Objeto, Db.TipoObjeto, Db.Indice, Db.TipoIndice

Order

By ‘Buffers Por Pgina’ Desc, TipoIndice Desc;

 

Pois bem galera, este é o Código – Script Challenge – 12, conto com a participação de vocês, envie seus comentário, críticas, sugestões e respostas para este desafio, e agora também com uma novidade, além de você descobrir o objetivo deste código, você também deverá identificar os possíveis erros ou inconsistências que possam existir.

Por enquanto é isso, volto no final deste mês com a resposta.

Até mais.

Resposta – Script Challenge 11


Pessoal, bom dia.

Como vocês estão? Alguma novidade?

Pois bem, como promessa é dívida, estou de volta com a resposta para mais um Script Challenger, agora na versão 2012, mais agressivo e desafiador.

Para aqueles que não participaram deste novo desafio, o código utilizado no Script Challenger 11, esta apresentado abaixo:

– Script Challenger 11 – Código 1 –

SELECT  OBJECT_NAME(s.[object_id]) AS [Table Name] ,

        i.name AS [Index Name] ,

        i.index_id ,

        user_updates AS [Total Writes] ,

        user_seeks + user_scans + user_lookups AS [Total Reads] ,

        user_updates – ( user_seeks + user_scans + user_lookups ) AS [Difference]

FROM  sys.dm_db_index_usage_stats AS s WITH ( NOLOCK ) INNER JOIN sys.indexes AS i WITH ( NOLOCK )

                                                                                                     ON s.[object_id] = i.[object_id]

                                                                                                     AND i.index_id = s.index_id

WHERE   OBJECTPROPERTY(s.[object_id], ‘IsUserTable’) = 1

AND s.database_id = DB_ID()

AND user_updates > ( user_seeks + user_scans + user_lookups )

AND i.index_id > 1

ORDER BY [Difference] DESC, [Total Writes] DESC, [Total Reads] ASC ;

Durante o período de tempo em que este desafio estava em aberto, recebi algumas observações e melhorias para o código, o que gostaria de agradecer a todos os participantes por estas sugestões.

Agora vou matar a curiosidade de todos e apresentar a resposta. Ao executar este código, o SQL Server ira realizar uma análise fazendo acesso entre a System View: sys.Indexes e a DMF sys.dm_db_index_usage_stats, a fim de identificar quais são os índices Não-Clusterizados que estão apresentando um Número de Escrita maior que o Número de Leituras, o que indica uma utilização incorreta do mesmo.

O grande segredo deste código encontra-se nestas linhas:

user_updates AS [Total Writes] ,

user_seeks + user_scans + user_lookups AS [Total Reads],

user_updates – ( user_seeks + user_scans + user_lookups ) AS [Difference]

Onde:

A coluna [Total Writes]: tem a finalidade de retornar a quantidade de escritas realizadas para cada índice identificado neste código;

A coluna [Total Reads]: tem a finalidade de retornar a quantidade de leituras realizadas para cada índice identificado neste código, com base, na soma das colunas: User_seeks + User_scans + User_lookups; e

A coluna [Difference]: tem a finalidade de apresenta a diferença entre o Total de Escritas e Totais de Leituras, com base, na subtração entre as colunas: user_updates – ( user_seeks + user_scans + user_lookups )

Esta diferença entre o Total de Escrita – o Total de Leituras, nos indica que este índice esta sendo nos Processos de Manipulação de Dados: Insert, Update e Delete, por outro lado, nos Processos de Pesquisa e Consulta: Select ele não esta envolvido em alguns casos o que pode representar que este índice é desnecessário ou esta sendo mal utilizado.

Qual é a importância deste código?

Basicamente demonstrar para o Desenvolvedor que nem sempre um índice é a melhor solução para aceleração e organizar uma pesquisa de dados, pois se o mesmo não esta sendo utilizado ele não representa um recurso que traga vantagens para o ambiente, muito pelo contrário, o mesmo pode estar somente ocupando espaço, ocasionando fragmentação e também com informações estatísticas desatualizadas por falta de uso.

Então pessoal é isso, vou encerrando aqui mais este desafio. Espero que todos possam ter gostado e que este código posso ser útil.

Agradeço mais uma vez a sua visita e participação.

Até mais.

Script Challenge – Número 11

Dica – Script Challenger – Número 11


Pessoal, boa tarde.

Tudo bem? Como foram de final de ano?

A vida não pode parar como também o conhecimento não pode deixar de ser transmitido, desta forma, estou relançando umas das principais sessões do meu Blog, que em 2011 teve muito destaque.

Ficou curioso?

Estou me referindo à sessão Script Challenger, lançada em 2011, com objetivo de fazer com que você leitor ou visitante do meu blog participa-se e ao mesmo tempo aprenda-se algo novo.

Nessa sessão o leitor, tem a possibilidade de dar a resposta deste desafio, como também apresentar uma outra possível forma de realizar a mesma rotina ou procedimento.

No ano de 2011 a Script Challenger, chegou até a edição de número 10, contando a participação de diversos colaboradores, neste ano vou manter a mesma forma de interação.

Postando novos scripts e durante um determinado período de tempo contando com a participação da comunidade na descoberta do que este script deve ou esta fazendo.

_______________________________________________________________________

Pois bem, vamos então começar o ano com o Script Challenger número 11, seguindo a número iniciado em 2011. A seguir apresento o Código 1:

— Script Challenger 11 – Código 1 —

SELECT  OBJECT_NAME(s.[object_id]) AS [Table Name] ,

        i.name AS [Index Name] ,

        i.index_id ,

        user_updates AS [Total Writes] ,

        user_seeks + user_scans + user_lookups AS [Total Reads] ,

        user_updates – ( user_seeks + user_scans + user_lookups ) AS [Difference]

FROM  sys.dm_db_index_usage_stats AS s WITH ( NOLOCK ) INNER JOIN sys.indexes AS i WITH ( NOLOCK )

                                                                                                     ON s.[object_id] = i.[object_id]

                                                                                                     AND i.index_id = s.index_id

WHERE   OBJECTPROPERTY(s.[object_id], ‘IsUserTable’) = 1

AND s.database_id = DB_ID()

AND user_updates > ( user_seeks + user_scans + user_lookups )

AND i.index_id > 1

ORDER BY [Difference] DESC, [Total Writes] DESC, [Total Reads] ASC ;

Quero contar com a sua participação neste novo desafio, envie seus comentários, observações ou a resposta, até do dia 20 de Janeiro.

Mais uma vez obrigado por sua visita e participação, nos encontramos em breve.

Até mais.

Resposta – Script Challenge – Número 9

Resposta – Script Challenger – Número 9.


Salve pessoal…

Estou de volta, agora com a resposta para o Script Challenger – Número 9, postado a algumas a semanas. Bom, para aqueles que não se lembram do código postado, segue abaixo novamente o script utilizado neste desafio.

– Script Challenge – Número 9 –

Create Trigger T_Calcular_Horas
On CTProducao_Moinho
For Insert, Update
As
Declare @TotalDias VarChar(4),
@TotalHoras VarChar(3),
@TotalMinutos VarChar(4),
@NUMMO CHAR(7),
@ValorFormatado Char(5)

Set @NUMMO=(Select NUMMO from Inserted)

Set @TotalDias=(Select DateDiff(Day,DataInicio,DataFinal) from CTProducao_Moinho Where NUMMO=@NUMMO)
Set @TotalHoras=(Select DateDiff(Hour,Convert(Char(20),DataInicio,103)+HoraInicio,Convert(Char(20),DataFinal,103)+HoraFinal) from CTProducao_Moinho Where NUMMO=@NUMMO)
Set @TotalMinutos=(Select DateDiff(Minute,Convert(Char(20),DataInicio,103)+HoraInicio,Convert(Char(20),DataFinal,103)+HoraFinal) from CTProducao_Moinho Where NUMMO=@NUMMO)

If @TotalDias >=2
Begin
Update CTProducao_Moinho
Set TotalHoras=@TotalHoras+’:00′
Where NUMMO=@NUMMO
End
Else
Begin
If (@TotalHoras >=1) And (@TotalHoras <=24)
Begin
If (@TotalHoras = 1) And (@TotalMinutos < 60)
Set @ValorFormatado=’00:’+@TotalMinutos

If (Len(@TotalHoras) = 1) And (@TotalMinutos > 60)
Begin
Set @ValorFormatado=Convert(Char(4),Convert(Int,@TotalMinutos)/Convert(Int,@TotalHoras))
Set @ValorFormatado=’0′+@TotalHoras+’:’+@ValorFormatado
End

If (Len(@TotalHoras) = 1)
Set @ValorFormatado=’0′+@TotalHoras+’:00′

If (Len(@TotalHoras) = 1) And (@TotalMinutos = 60)
Set @ValorFormatado=’0′+@TotalHoras+’:00′

Update CTProducao_Moinho
Set TotalHoras=@ValorFormatado
Where NUMMO=@NUMMO
End
Else
Begin
If @TotalMinutos=60
Begin
Update CTProducao_Moinho
Set TotalHoras=’01:00′
Where NUMMO=@NUMMO
End
Else
Begin
If Len(@TotalMinutos) = 1
Set @ValorFormatado=’00:0′+@TotalMinutos
Else
Set @ValorFormatado=’00:’+@TotalMinutos

Update CTProducao_Moinho
Set TotalHoras = @ValorFormatado
Where NUMMO=@NUMMO
End
End
End

Pois bem, você conseguiu encontrar a respostas para este Código? Diversos participantes me enviaram por e-mail suas respostas, alias foram diversas, eu fiquei surpreso, pois este desafio apresentou o maior número de respostas obtidas até agora. Foram aproxidamente 100 respostas, com observações, dicas, críticas e comentários sobre o código.

Para aqueles que não participaram, a resposta deste Script Challenger – Número 9 é muito simples.

Como vocês podem observar, trata-se de um Trigger chamado T_Calcular_Horas vínculado a tabel CTProducao_Moinho, disparado na ocorrências de Inserts e Updates.

A função básica deste trigger e análisar através de algumas condições uma possível diferenção entre horas, minutos e segundos para formatar o valor de preenchimento do campo TotalHoras, utilizado em um ERP para controle de qualidade na área de produção de uma indústria que trabalhei a algum tempo.

De acordo com o valores de diferença, realizo a concatenação dos valores e posteriormente, a trigger executa um Update sobre a Table CTProducao_Moinho diretamente no campo TotalHoras.

Vale ressaltar que este script respeita algumas regras de negócios da empresa e também do ERP por isso, foi necessário realizar estas análises, conversões e concatenações de valores.

Muito bem galera, esta aqui a resposta, espero que todos possam ter entendido e gostado.

Nos encontramos nos próximos Script Challenger.

Até mais.

Script Challenge – Número 9

Script Challenge – Número 9.


Salve comunidade, Tudo bem?

Estou de volta com mais um Script Challenge, agora na edição de número 9. Alias a algumas semanas eu deixei de postar alguns artigos no meu fórum devido a algumas situações que estavam colocando a minha imagem e experiência em dúvida perante a comunidade Microsoft. Passados alguns dias, voltamos a vida normal e vamos em frente.

Bom, como de costume vou postar o código e contar com a participação de todos através de e-mails, comentários, twitters, entre outros.

Segue abaixo o código do Script Challenge – Número 9:

— Script Challenge – Número 9 —

Create Trigger T_Calcular_Horas
On CTProducao_Moinho
For Insert, Update
As
Declare @TotalDias VarChar(4),
@TotalHoras VarChar(3),
@TotalMinutos VarChar(4),
@NUMMO CHAR(7),
@ValorFormatado Char(5)

Set @NUMMO=(Select NUMMO from Inserted)

Set @TotalDias=(Select DateDiff(Day,DataInicio,DataFinal) from CTProducao_Moinho Where NUMMO=@NUMMO)
Set @TotalHoras=(Select DateDiff(Hour,Convert(Char(20),DataInicio,103)+HoraInicio,Convert(Char(20),DataFinal,103)+HoraFinal) from CTProducao_Moinho Where NUMMO=@NUMMO)
Set @TotalMinutos=(Select DateDiff(Minute,Convert(Char(20),DataInicio,103)+HoraInicio,Convert(Char(20),DataFinal,103)+HoraFinal) from CTProducao_Moinho Where NUMMO=@NUMMO)

If

@TotalDias >=2
Begin
Update CTProducao_Moinho
Set TotalHoras=@TotalHoras+’:00′
Where NUMMO=@NUMMO
End
Else
Begin
If (@TotalHoras >=1) And (@TotalHoras <=24)
Begin
If (@TotalHoras = 1) And (@TotalMinutos < 60)
Set @ValorFormatado=’00:’+@TotalMinutos

If (Len(@TotalHoras) = 1) And (@TotalMinutos > 60)
Begin
Set @ValorFormatado=Convert(Char(4),Convert(Int,@TotalMinutos)/Convert(Int,@TotalHoras))
Set @ValorFormatado=’0’+@TotalHoras+’:’+@ValorFormatado
End

If (Len(@TotalHoras) = 1)
Set @ValorFormatado=’0’+@TotalHoras+’:00′

If (Len(@TotalHoras) = 1) And (@TotalMinutos = 60)
Set @ValorFormatado=’0’+@TotalHoras+’:00′

Update CTProducao_Moinho
Set TotalHoras=@ValorFormatado
Where NUMMO=@NUMMO
End
Else
Begin
If @TotalMinutos=60
Begin
Update CTProducao_Moinho
Set TotalHoras=’01:00′
Where NUMMO=@NUMMO
End
Else
Begin
If Len(@TotalMinutos) = 1
Set @ValorFormatado=’00:0’+@TotalMinutos
Else
Set @ValorFormatado=’00:’+@TotalMinutos

Update CTProducao_Moinho
Set TotalHoras = @ValorFormatado
Where NUMMO=@NUMMO
End
End
End

Galera, pronto, esta lançado mais este desafio, conto com vocês.

Até mais.

Resposta – Script Challenge – Número 8

Resposta – Script Challenge – Número 8


Pessoal, boa tarde.

Passado diversos dias, estou de volta com a resposta para o nosso Script Challenge – Número 8, alias, obtive diversas respostas sobre este código, o que me deixou muito surpreso com as análises dos colegas.

Para você que não visitou o post anterior, segue abaixo o código utilizado em mais este desafio:

— Código – Script Challenge – Número 8 —

declare @Dia int
select @Dia = DATEPART (weekday ,getdate())
if @Dia = 1
begin
backup database DBQUADRANT_BI to disk = ‘D:\backup\domingo\DBQUADRANT.BAK’ with init, noformat
end
if @Dia = 2
begin
backup database DBQUADRANT_BI to disk = ‘D:\backup\segunda\DBQUADRANT.BAK’ with init, noformat
end
if @Dia = 3
begin
backup database DBQUADRANT_BI to disk = ‘D:\backup\terca\DBQUADRANT.BAK’ with init, noformat
end
if @Dia = 4
begin
backup database DBQUADRANT_BI to disk = ‘D:\backup\quarta\DBQUADRANT.BAK’ with init, noformat
end
if @Dia = 5
begin
backup database DBQUADRANT_BI to disk = ‘D:\backup\quinta\DBQUADRANT.BAK’ with init, noformat
end
if @Dia = 6
begin
backup database DBQUADRANT_BI to disk = ‘D:\backup\sexta\DBQUADRANT.BAK’ with init, noformat
end
if @Dia = 7
begin
backup database DBQUADRANT_BI to disk = ‘D:\backup\sabado\DBQUADRANT.BAK’ with init, noformat
end

Qual então seria a finalidade deste código?

Bom como já pode ter sido percebido trata-se de um script utilizado para processos de backup, basicamente, neste código podemos configurar o nosso backup para ser realizado e armazenado conforme o dia semana em uma pasta diferente.
Através da variável @dia utilizada para receber o valor do dia da semana com base no retorno da função DatePart, o SQL Server vai analisar qual é o valor da varíavel, e fazendo uso do comando condicional IF o backup será realizado e armazenada em um local diferente.
Então foi difícil descobrir o que o código utilizado no Script Challenge – Número 8, realiza?
Bom, esta aqui mais uma pequena dica que poderá automatizar ainda mais o seu ambiente de trabalho. Espero ter ajudado e apresentado de forma simples como podemos combinar a utilização de variáveis, funções e comando de análise condicional em nossos Scripts.
Por enquanto é isso, já estou preparando nosso próximo Script Challenge – Número 9. Teremos surpresas.
Até mais.