Microsoft Safety Scanner v1.0.3001.0


O Microsoft Safety Scanner v1.0.3001.0 é uma ferramenta de verificação projetada para localizar e remover malware de computadores com Windows.

Basta baixá-lo e executar uma verificação para localizar malware e tentar reverter as alterações feitas por ameaças identificadas.

O Safety Scanner só verifica quando executado manualmente e está disponível para uso 10 dias após o download. A Microsoft recomenda que você sempre baixe a versão mais recente dessa ferramenta antes de cada verificação.

Observação: O Microsoft Safety Scanner NÃO substitui um software antivírus. Para ajudar a proteger seu computador, use um software antivírus e mantenha-o sempre atualizado.

O Microsoft Safety Scanner v1.0.3001.0 está disponível para download aqui em versões 32 e 64 bits e pode ser usado no Windows 10, Windows 8/8.1, Windows 7, Windows Server 2016, Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 e no Windows Server 2008.

Imagens do Microsoft Safety Scanner v1.0.3001.0:

Microsoft Safety Scanner v1.0.3001.0
O Safety Scanner só verifica quando executado manualmente e está disponível para uso 10 dias após o download. A Microsoft recomenda que você sempre baixe a versão mais recente dessa ferramenta antes de cada verificação



Fontes e Direitos Autorais: Microsoft.com – https://www.microsoft.com/en-us/wdsi/products/scanner#

Anúncios
Publicado em Ameaças, Curiosidades, Diversos, Ferramentas, Inovações, Microsoft, Segurança, Sistema Operacional, Utilitários, Vírus, Windows | Marcado com , , , , , , , | Deixe um comentário

Microsoft SQL Server 2012 SP4 liberado


Anunciado no final de junho pela Microsoft, o SQL Server 2012 SP4 (Service Pack 4) foi disponibilizado para download nesta semana pela empresa.

O Feature Pack e a versão Express com o SP4 também estão disponíveis.

SQL Server 2012 SP4

De acordo com a Microsoft, o SQL Server 2012 SP4 será o último Service Pack para a versão 2012 do SQL Server e além de ser uma coleção de hotfixes, ele também traz mais de 20 melhorias com foco na performance, escalabilidade e diagnóstico com base no feedback de clientes e da comunidade.

Mais especificamente, o Service Pack 4 inclui:

– Todas as correções e atualizações cumulativas para o SQL Server 2012.

– Melhorias na performance e escalabilidade.

– Recursos de monitoramento adicionais através de melhorias no DMV, Extended Events e Query Plans.

– Melhorias com base no feedback da comunidade.

– Melhorias introduzidas originalmente pelo SQL Server 2014 SP2 e SQL Server 2016 SP1.

Faça o download do SQL Server 2012 SP4

O SQL Server 2012 SP4 está disponível para download através deste link. Ele pode ser usado para atualizar instalações existentes do SQL Server 2012.

A versão Express, que é gratuita, já com o SP4 está disponível para download aqui e o Feature Pack está disponível para download aqui.

O Service Pack está disponível para download no centro de download da Microsoft e também será disponibilizado na Galeria de imagens Azure, MSDN, fonte MBS/Partner e VLSC nas próximas semanas. Como parte do nosso compromisso contínuo com a excelência de software para nossos clientes, essa atualização está disponível para todos os clientes com implantações do SQL Server 2012 existentes.

Para maiores informações acesse:

SQL Server 2012 SP4
SQL Server 2012 SP4 Feature Pack
SQL Server 2012 Service Pack 4 Release Information

Fontes e Direitos Autorais: MSSQL Tiger Team – SQL Server Engineering Team – 05/10/2017 – https://blogs.msdn.microsoft.com/sql_server_team/sql-server-2012-service-pack-4-sp4-is-now-available/

Publicado em Ameaças, Azure, Backup, Banco de Dados, Banco de Dados, Correções, Curiosidades, DBA, Desenvolvimento, Diversos, Hardware, Inovações, Internet, Microsoft, MSDN, Mundo SQL Server, Notícias, Segurança, Sistema Operacional, SQL Server, TechNet, Transact-SQL, Utilitários, Vírus, VIRTUAL PASS BR, Virtualização, Visual Studio, Windows, Windows Server | Marcado com , , , , , , , , , , , , , , , , , , , , , , , , | Deixe um comentário

#16 – Para que serve


Fala galera, boa noite.

Último dia do mês de setembro e como costumo dizer o tempo esta passando a cada dia de uma maneira mais rápida que não conseguimos nos deparar com tudo o que acontece ao nosso redor.

São exatamente 22:07 hrs da noite de um sábado que já esta chegando ao fim e com ele o final também de mais um mês de muita luta e trabalho neste ano de 2017, eita ano complicado.

Mas se você esta lendo este post é porque de alguma maneira acabou chegando até aqui, muito obrigado por sua visita, sendo este o post de número 16 da sessão Para que serve, já estava passando da hora de publicar mais um conteúdo exclusivo para esta sessão.

O conteúdo de hoje é um assunto que eu pouco trabalhei em toda minha carreira de DBA, olha que já fazem 17 anos que venho me dedicando diariamente a esta função, mas o recurso que será destacado hoje não é assim “tão velhinho” como eu (kkkkk).

Hoje vou destacar um pouco sobre índices, ai você pode se perguntar, poxa vida você pouco trabalhou com índices, como assim? Pois é, a resposta tão uma pequena perda de verdade, o tipo de índice ao qual eu me refiro pois adicionado ao Microsoft SQL Server a partir da versão 2012, agora acredito que ficou fácil saber de qual índice estou me referindo, se você ainda não se lembrou ou não se atentou para a dica, estou me referindo ao ColumnStore Index. Agora, tenho a certeza que você se lembrou desta nova forma de armazenamento de dados criada pelo time de engenheiros do Microsoft SQL Server a partir da versão 2012 e que ao longo das próximas versões sofreu diversas atualizações e melhorias.

Se a sua resposta é não ou sinceramente você não conhece esta “nova maneira” de trabalhar com índice, não fique preocupado, como de costume vou fazer uma breve introdução sobre este recurso, como também, vamos fazer alguns comparativos em relação a espaço em disco ocupado e custo de processamento em relação aos tradicionais índices Clustered e NonClustered, sendo estes conhecidos como índices Row Store.

Então chegou a hora de conhecer um pouco mais sobre este recurso, desta forma, seja bem vindo ao #16 – Para que serve – Algumas características e comportamentos do ColumnStore Index.

Introdução

Segundo a documentação oficial do Microsoft SQL Server,  índice columnstore é o padrão para armazenar e consultar grandes tabelas de fatos de repositório de dados. 

Um columnstore index é uma tecnologia para armazenamento, recuperação e gerenciamento de dados usando um formato de dados colunar, chamado columnstore.

Ele usa armazenamento de dados baseado em coluna e processamento de consultas para alcançar um desempenho de consulta até 10 vezes melhor no data warehouse em relação ao armazenamento tradicional orientado por linha e até 10 vezes mais compactação de dados em relação ao tamanho dos dados descompactados.

A partir do SQL Server 2016, os índices columnstore permitem a análise operacional, a capacidade de executar análises de alto desempenho em tempo real em uma carga de trabalho transacional. 

ColumnStore Vs RowStore

Um columnstore são dados logicamente organizados como uma tabela com linhas e colunas e fisicamente armazenados em um formato de dados com reconhecimento de coluna.

Um rowstore são dados logicamente organizados como uma tabela com linhas e colunas e fisicamente armazenados em um formato de dados com reconhecimento de linha. No SQL Server, rowstore refere-se à tabela em que o formato de armazenamento de dados subjacente é um heap, um índice clusterizado ou uma tabela com otimização de memória.

Característica 1: Por padrão até a versão 2012 todo e qualquer índice do tipo Clustered e NonClustered ao ser criado era associado ao mesmo uma estrutura de armazenamento de dados utilizando a tecnologia de RowStore, neste caso, ao invés de conter somente a coluna relacionada ao índice o mesmo possuía a linha por completa o que acarretava um aumento considerável de espaço em disco, como também, um custo de processamento maior para o SQL Server quando o dado solicitado era pesquisado.

Seguindo em frente, já sabemos um pouco sobre esta nova maneira de se armazenar dados contidos em um índice, característica muito importante e que pode nos trazer grandes benefícios.

Quais podem ser os outros benefícios ou características nativas existentes no ColumnStore Index que podem nos fazer adotar este tipo de tecnologia? Esta e muitas outras perguntas que eu mesmo sempre fiz em relação á este tipo de índice serão respondidas a seguir, através do ambiente que estaremos utilizando neste post.

Ambiente

Para que possamos entender ainda mais sobre o ColumnStore Index, nada melhor do que colocar em prática este recurso, para tal vamos começar a montar nosso ambiente de teste, composto por três tabelas similares denominadas:

  • MassaDeDadosCompressaoPorRow;
  • MassaDeDadosCompressaoPorPage; e
  • MassaDeDadosCompressaoColumnStore.

Estes três tabelas serão formadas por duas simples colunas denominadas:

  • Record; e
  • Number.

Onde a coluna Record será utilizada como identificar das linhas de registros que estão sendo manipuladas, sendo seu valor preenchido de forma automática através da propriedade Identity().

A coluna Number corresponde ao número que será inserido de forma aleatório neste coluna, esta será a coluna que iremos utilizar para a construção dos respectivos índices em cada tabela.

Vamos então através do Bloco de Código 1 realizar a criação de cada tabela, suas colunas e seus respectivos índices. Vale ressaltar que além de índices nas tabelas MassaDeDadosCompressaoPorRow e MassaDeDadosCompressaoPorPage estamos também utilizando compressão de dados aplicada a linha e compressão de dados aplicada a página de dados respectivamente. 

A seguir apresento o Bloco de Código 1:

— Bloco de Código 1 —

Use TempDB
Go

Create Table dbo.MassaDeDadosCompressaoPorRow
(Record Bigint Identity(1,1),
 Number BigInt
 Index IND_MassaDeDadosCompressaoPorRow Clustered (Number))
WITH (DATA_COMPRESSION = ROW)
Go

Create Table dbo.MassaDeDadosCompressaoPorPage
(Record Bigint Identity(1,1),
 Number BigInt
 Index IND_MassaDeDadosCompressaoPorPage Clustered (Number))
WITH (DATA_COMPRESSION = PAGE)
Go

Create Table dbo.MassaDeDadosCompressaoPorColumnStore
(Record Bigint Identity(1,1),
 Number BigInt,

 INDEX IND_MassaDeDadosCompressaoPorColumnStore Clustered  ColumnStore)
Go

Por enquanto nada de muito inovador ou diferente do que você pode estar acostumado a fazer, mas uma segunda característica do ColumnStore Index pode ser identificada após a criação das tabelas.

Característica 2: Ao realizar a criação de um índice ColumnStore, o Storage Engine mecanismo utilizado pelo Microsoft SQL Server para armazenamento físico de dados, realiza a alocação de um espaço mínimo inicial para armazenar a estrutura base da coluna relacionada ao índice, ou seja, mesmo não possuindo não dado armazenado no ColumnStore um pequeno espaço em disco é ocupado por sua estrutura e respectiva coluna. Para comprovar esta característica utilizamos o Bloco de Código 2 apresentado abaixo:

— Bloco de Código 2 —

Select s.Name As SchemaName, t.Name As TableName, p.rows As RowCounts,
            Cast(Round((Sum(a.used_pages) / 128.00), 2) As Numeric(36,2)) As Used_MB,
             Cast(Round((Sum(a.total_pages) – SUM(a.used_pages)) / 128.00, 2) As Numeric(36, 2)) As Unused_MB,
            Cast(Round((Sum(a.total_pages) / 128.00), 2) As Numeric(36, 2)) As Total_MB
From sys.tables t Inner Join sys.indexes i
                                 On t.OBJECT_ID = i.object_id
                                Inner Join sys.partitions p
                                 On i.object_id = p.OBJECT_ID And i.index_id = p.index_id
                                Inner Join sys.allocation_units a
                                On p.partition_id = a.container_id
                                 Inner Join sys.schemas s
                                 On t.schema_id = s.schema_id
Where t.object_id >1
Group By t.Name, s.Name, p.Rows
Order By s.Name, t.Name
Go 

Agora que você executou o Bloco de Código 2, deve ter obtido como resultado ao similar ao apresentado na Figura 1 a seguir:


Figura 1 – Espaço ocupado pelo ColumnStore Index mesmo são a existência de linhas de registro.

Legal, mas ainda temos algumas coisas para analisar em relação ao ColumnStore Index, nosso próximo passo será realizar o armazenamento de uma massa de dados em cada tabela, aonde estará identificando o tempo de processamento decorrido para inserir um milhão de linhas de registro, valor hoje considerado pouco para se trabalhar com qualquer banco de dados e principalmente para estruturas ColumnStore, mas o suficiente para nossas análises e comparações.

Vamos então trabalhar com o Bloco de Código 3 a seguir:

— Bloco de Código 3 —

— Inserindo 1.000.000 na Tabela MassaDeDadosCompressaoPorRow –|

Declare @Contador Int = 1

While @Contador <=1000000
Begin
Insert Into dbo.MassaDeDadosCompressaoPorRow (Number)
Values (Rand()*1000000000000)

Set @Contador +=1
End
Go

— Inserindo 1.000.000 na Tabela MassaDeDadosCompressaoPorPage —

Declare @Contador Int = 1

While @Contador <=1000000
Begin
Insert Into dbo.MassaDeDadosCompressaoPorPage (Number)
Values (Rand()*1000000000000)

Set @Contador +=1
End
Go

— Inserindo 1.000.000 na Tabela MassaDeDadosCompressaoPorColumnStore —

Declare @Contador Int = 1

While @Contador <=1000000
Begin
Insert Into dbo.MassaDeDadosCompressaoPorColumnStore (Number)
Values (Rand()*1000000000000)

Set @Contador +=1
End
Go

Neste momento nossas tabelas já estão totalmente populadas com 1.000.000 de linhas de registros armazenadas em cada uma delas, vamos então identificar mais duas características presentes no ColumnStore Index, começando pela número 3.

Característica 3: ColumnStore Index apresentam em alguns cenários de armazenamento de dados dependendo do tipo de dados utilizado por ele uma ligeira perda de performance em comparação com o mesmo tipo de dados utilizado em índices que utilizam tecnologia RowStore.

Para comprovar e ajudar a entender esta diferença de comportamento apresento a seguir a Tabela 1 que exibe os dados coletados durante os três processos de inserir realizado pelo Bloco de Código 3 declarado anteriormente.

Tabela Operação Tempo Decorrido
MassaDeDadosCompressaoPorRow Insert 00:00:22
MassaDeDadosCompressaoPorPage Insert 00:00:22
MassaDeDadosCompressaoPorColumnStore Insert 00:00:28

Tabela 1 – Comparativo de tempo decorrido para inserção de 1.000.000 de linhas de registro em cada tabela.

Nossa próxima característica esta relacionada ao espaço físico ocupado em disco para cada índice de acordo com a tecnologia de armazenamento utilizada e a forma de compressão aplicada.

Característica 4: Tabelas que possuem índice do tipo ColumnStore ocupam um espaço físico em disco infinitamente menor que tabelas que possuem índices RowStore, o que representa que o espaço ocupado em disco por índices que utilizam tecnologia ColumnStore podem apresentar uma economia de espaço em disco entre 70 e 90%, algo que devemos considerar em muito quando vamos trabalhar com um volume consideravelmente grande de dados.

A Tabela 2 apresentada abaixo ilustra esta diferença de espaço em disco ocupada por cada tabela:

Dados coletados pelo SP_SpaceUsed
Tabela Linhas Espaço Reservado  Dados Índices Não Utilizado
dbo.MassaDeDadosCompressaoPorRow 1000000 18592 KB 18448 KB 104 KB 40 KB
dbo.MassaDeDadosCompressaoPorPage 1000000 17312 KB 17192 KB 96 KB 24 KB
dbo.MassaDeDadosCompressaoPorColumnStore 1000000 28904 KB 28696 KB 144 KB 64 KB

Tabela 2 – Dados coletados pela System Stored Procedure SP_SpaceUsed.

Observação: Se analisarmos os dados da Tabela 2 podemos notar que a compressão por página de dados para este cenário de 1.000.000 de linhas de registro foi um pouco superior em relação a economia de espaço em disco se comparada com a compressão por linha de dados, essa é uma característica interessante quando trabalhamos com compressão de dados fazendo uma análise de minimal space entre Row Compression e Page Compression.

Uma outra possibilidade para notar esta diferença considerável de espaço alocado, reservado e ocupado fisicamente em disco poderia ser obtido através de uma nova execução do Bloco de Código 2 apresentado anteriormente, para tal a Tabela 3 apresenta o resultado desta nova execução:

Dados coletados através do Bloco de Código 2
Tabela Linhas Espaço Ocupado em MBs Espaço Não Utilizado em MBs Total MBs
MassaDeDadosCompressaoPorRow 1000000 18.12 0.04 18.16
MassaDeDadosCompressaoPorPage 1000000 16.88 0.02 16.91
MassaDeDadosCompressaoPorColumnStore 1000000 0.02 0.05 0.07

Tabela 3 – Dados coletados através da execução do Bloco de Código 2.

Observação: No que diz respeito a minimal space quando trabalhamos com o ColumnStore Index em comparação com Row Compression ou Page Compression a diferença é extremamente assustadora, aonde o ColumnStore Index aplica uma técnica de armazenamento de dados muito interessante que possibilita esta ganho de espaço e consequentemente ganho de performance. Esta técnica é conhecida como Row Group.

Estamos quase no final, vamos agora identificar mais uma importante característica presente em um ColumnStore Index, relacionada a performance algo que este tipo de tecnologia apresenta como principal vantagem e benefícios em relação a índices RowStore ainda mais quando trabalhamos com grandes volumes de dados em ambientes relacionais.

Nossa análise será iniciada através da execução da Bloco de Código 4 declarado abaixo, observe que estaremos habilitando os contadores de estatísticas de processamento relacionados a Tempo e Input/Output denominados:

Através do uso destes contadores o Management Studio ira nos retornar na guia de mensagens um conjunto de dados relacionados ao tempo de processamento, quantidade de leituras lógicas e físicas demandadas por cada transação que estaremos processando, com base, nestes e outros dados poderemos identificar quando será o diferença do ColumnStore Index em comparação com os outros índices existentes em nossas tabelas.

Outro elemento importante que estaremos utilizando, consiste na quantidade de linhas pesquisadas em cada tabela, você poderá notar que para cada Select declarado no Bloco de Código 4 estaremos filtrando e limitando nosso result set na faixa de valores existentes entre as linhas de registro 525.000 e 789.000.

Vamos então executar o Bloco de Código 4, recomendo que faça a execução de cada select de forma separada, anote os dados retornados pelos contadores Time e IO:

— Bloco de Código 4 —

Set Statistics Time On
Set Statistics IO On
Go

Select * from dbo.MassaDeDadosCompressaoPorRow
Where Record Between 525000 And 789000
Go

Select * from dbo.MassaDeDadosCompressaoPorPage
Where Record Between 525000 And 789000
Go

Select * from dbo.MassaDeDadosCompressaoPorColumnStore
Where Record Between 525000 And 789000
Go

Set Statistics Time Off
Set Statistics IO Off
Go

Ufa, estamos quase lá, nosso Bloco de Código 4 foi apresentado, tenho a certeza que você executou cada Select de forma individual, anotando os respectivos valores de tempo de processamento e input/output retornados pelo SQL Server, muito bem, agora vamos analisar a Tabela 4 apresentada abaixo e identificar o comportamento apresentado pelo ColumnStore Index.

Tabela Operação Tempo Decorrido CPU Time Elapsed Time Scan Count Logical Reads Physical Reads
MassaDeDadosCompressaoPorRow Select 00:00:02 110 ms 769 ms 1 2316 0
MassaDeDadosCompressaoPorPage Select 00:00:02 203 ms 830 ms 1 2158 0
MassaDeDadosCompressaoPorColumnStore Select 00:00:01 125 ms 911 ms 2 3599 0

Tabela 4 – Conjunto de dados coletados e apresentados pelos contadores TIME e IO durante a execução dos selects declarados no Bloco de Código 4.

Característica 5: Índice do tipo ColumnStore sempre serão mais rápidos que índice RowStore mesmo apresentando alguns dados que valores superiores, dentre eles: Scan Count e Logical Reads.

Analisando os dados apresentados anteriormente na Tabela 4, fica mais fácil observar alguns comportamentos presentes em índices ColumnStore, nos quais a quantidade de leituras lógicas pode estar mais presente neste tipo de índice devido justamente a sua forma de armazenamento de dados, além disso, o número de contagem de varreduras conhecidos como Scan Count, outro fator que também esta relacionado ao armazenamento do dados no índice na forma de coluna ao invés de linha como no RowStore.

Mas o elemento mais importante esta vinculado ao tempo decorrido na busca dos dados solicitados, tanto a tabela MassaDeDadosCompressaoPorRow como também a MassaDeDadosCompressaoPorPage demandaram 00:00:02 segundos para identificar, filtrar e apresentar 264.001 mil linhas de registro.

Nesta mesma comparação, os dados pesquisados na tabela MassaDeDadosCompressaoPorRow foram retornados em tela em 00:00:01 segundo, ou seja, uma ligeira diferença no tempo de processamento, o que pode parecer muito insignificante para o atual volume de dados que estamos trabalhando, mas imagine este ganho de processamento quando estivermos manipulando bilhões, trilhões ou quatrilhões de linhas de dados, mesmo que o elapsed time do processamento tenha sido um pouco maior que os demais. 

Desta forma, os dados apresentados na Tabela 4 em conjunto com os demais dados presentes em cada análise realizada neste post, nos traz a seguinte certeza, que índices ColumnStore podem e devem ser analisados, o que nos permite também dizer que o uso deste tipo de tecnologia poderá ser de grande avaliar e benefícios no que se relaciona a armazenamento e processamento de dados.

Com isso chegamos ao final deste post, olha foi surpreende e desafiador….


Referências

https://docs.microsoft.com/en-us/sql/relational-databases/data-compression/row-compression-implementation

https://docs.microsoft.com/en-us/sql/relational-databases/data-compression/page-compression-implementation

https://docs.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property

https://docs.microsoft.com/en-us/sql/relational-databases/data-compression/data-compression

https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-spaceused-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/indexes/columnstore-indexes-overview

https://docs.microsoft.com/en-us/sql/t-sql/statements/set-statistics-time-transact-sql

https://docs.microsoft.com/en-us/sql/t-sql/statements/set-statistics-io-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-tables-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-indexes-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-partitions-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-allocation-units-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/schemas-catalog-views-sys-schemas

Links

Caso você ainda não tenha acessado os posts anteriores desta sessão, fique tranquilo é fácil e rápido, basta selecionar um dos links apresentados a seguir:

https://pedrogalvaojunior.wordpress.com/2017/06/28/15-para-que-serve/

https://pedrogalvaojunior.wordpress.com/2017/04/30/14-para-que-serve/

https://pedrogalvaojunior.wordpress.com/2017/03/25/13-para-que-serve/

https://pedrogalvaojunior.wordpress.com/2017/01/23/12-para-que-serve/

Conclusão

Identificar a melhor forma de armazenar nossos dados em um Sistema Gerenciador de Banco de Dados não é um tarefa das mais fáceis e comum de se realizada, escolher qual tecnologia de armazenamento visando economia de espaço e performance muito menos.

A partir da versão 2012 do Microsoft SQL Server esta tarefa começou a ficar um pouco mais interessante e amigável com a adoção da tecnologia de armazenamento de dados existentes em um índice no formato de coluna ao invés de linha, tecnologia conhecida e denominada como ColumnStore Index.

O uso do ColumnStore Index deve ser avaliado, sua principal característica relaciona-se ao capacidade de processamento de um grande volume de dados com baixo custo de tempo, mesmo em ambientes relacionais, o que nos permite dizer que utilizar um índice ColumnStore poderá lhe trazer benefícios tanto no espaço ocupado em disco, bem como, no tempo de processamento na pesquisa de dados.

Agradecimentos

Antes de finalizar, são 00:46hrs da madrugada, já estamos no dia 01/10, ou seja, um novo mês esta começando neste domínio.

Chegou a hora do descanso, se preparar para um novo dia que daqui a pouco estará raiando, espero que você possa fazer o mesmo, aproveitar o seu dia ainda mais um domingo, tentar viver um pouco sem se preocupar com os problemas.

Mais uma vez obrigado por sua ilustre visita, sinto-me honrado com sua presença, espero que este conteúdo possa lhe ajudar e ser útil em suas atividades profissionais e acadêmicas.

Um forte abraço, até o próximo post da sessão Para que serve…..

Valeu.

Publicado em Azure, Banco de Dados, Banco de Dados, Curiosidades, DBA, Desenvolvimento, Dicas, Diversos, Educação, Ferramentas, Hardware, Inovações, Interoperabilidade, Linux, Microsoft, MSDN, Mundo SQL Server, Notícias, Para que serve, Sistema Operacional, SQL Server, TechNet, TI Verde, Transact-SQL, Utilitários, VIRTUAL PASS BR, Virtualização, Visual Studio, Visual Studio, Windows, Windows Core, Windows Server | Marcado com , , , , , , , , , , , , , , , , , , , , , , , , | Deixe um comentário

Curso de Extensão – Fundamentos de Data Warehouse e BI


Olá pessoal, bom dia.

Tudo bem?

Em parceria com a Fundação FAT e Fatec São Roque, estarei realizando no mês de outubro um novo curso de extensão voltado para área de análise de dados, mais especificamente sobre Data Warehouse e Business Intelligence.

Ficou interessado sobre o curso? A seguir você poderá encontrar maiores detalhes e informações.

INSCRIÇÕES
Entre 20 de Setembro a 10 de Outubro de 2017
Modalidade Presencial : 28 horas aulas distribuídas ao longo de 07 dias.
Realização : nos dias 16, 17, 18, 19, 20, 23 e 24 de Outubro de 2017 . 
Horário 01 (uma) turma : das 08:00 as 12:00h

CURSO
Este curso visa transmitir aos alunos os conhecimentos básicos dos sistemas de informação de uma empresa, com ênfase na utilização do sistema de apoio a decisão como importante sustentação para otimizar os resultados desejados, mediante a coleta, seleção, armazenamento, processamento e recuperação de dados para prover os executivos das informações relevantes, passadas, presentes e futuras, sobre a empresa e o ambiente, possibilitando tomadas de decisão com o mínimo de incerteza. 

Permitir uma visão clara das técnicas aplicáveis para a construção de um data warehouse, ferramentas, recursos e ciclo de vida, para o desenvolvimento de projetos de data warehouse, que é ajustado às necessidades do negócio


CONTEÚDO PROGRAMÁTICO
• Conceitos básicos. 
• Sistemas de Apoio à Decisão. 
• Os Ecossistemas de Informação. 
• O Ciclo de Vida do DW: Planejamento e Administração, Levantamento de Requisitos, Arquiteturas e Business Intelligence.

METODOLOGIA

• Exercícios práticos em laboratório e prova valendo nota para aprovação
• Serão aprovados e receberão o Certificado de Conclusão do Curso os alunos que cumprirem todas as atividades obrigatórias estabelecidas pela 
avaliação, nos prazos determinados e atingirem níveis de qualidade compatíveis com os objetivos de formação estabelecidos pelo Plano de Curso.

LOCAL E REALIZAÇÃO
Campus da FATEC São Roque
Investimento: R$ 200,00 ou Matricula (R$ 100,00) + 01 parcela (R$ 100,00) – Boleto Bancário.
Dúvidas: Pedro Antonio Galvão Junior – pedro.galvao3@fatec.sp.gov.br

Para realizar a inscrição clique aqui


Agradeço a sua atenção, nos encontramos em breve.

Até mais.

Publicado em Banco de Dados, Banco de Dados, Carreira, Curiosidades, DBA, Desenvolvimento, Educação, Ferramentas, Interoperabilidade, Linux, Microsoft, MSDN, Mundo SQL Server, Sistema Operacional, SQL Server, TechNet, Transact-SQL, Treinamento, Utilitários, VIRTUAL PASS BR, Virtualização, Windows | Marcado com , , , , , , , , , , , , , , , , , , , , , , , , | Deixe um comentário

Microsoft SQL Server Migration Assistant v7.6


A Microsoft disponibilizou para download nesta semana o Microsoft SQL Server Migration Assistant v7.6. Disponível para MySQL, SAP Adaptive Server Enterprise (ex-Sybase), Oracle Database, IBM DB2 e Access, o Microsoft SQL Server Migration Assistant é uma ferramenta gratuita que simplifica o processo de migração destes produtos para o SQL Server e Azure SQL.

A ferramenta automatiza todos os aspectos da migração. A versão 7.6 inclui o suporte para:

– Migração do MySQL 4.1 e posteriores para todas as edições do SQL Server 2008, SQL Server 2008 R2, SQL Server 2012, SQL Server 2014, SQL Server 2016, SQL Server 2017 e Azure SQL DB.

– Migração do Access 97 e posteriores para todas as edições do SQL Server 2012, SQL Server 2014, SQL Server 2016, SQL Server 2017 e Azure SQL DB.

– Migração do SAP Adaptive Server Enterprise (ex-Sybase) 11.9 e posteriores para todas as edições do SQL Server 2008, SQL Server 2008 R2, SQL Server 2012, SQL Server 2014, SQL Server 2016, SQL Server 2017 e Azure SQL DB.

– Migração do Oracle Database 9.0 e posteriores para todas as edições do SQL Server 2008, SQL Server 2008 R2, SQL Server 2012, SQL Server 2014, SQL Server 2016, SQL Server 2017, Azure SQL DB e Azure SQL Data Warehouse.

– Migração do IBM DB2 9.0 e 10.0 no z/OS e das versões 9.7 e 10.1 no Linux/Unix/Windows para o SQL Server 2012, SQL Server 2014, SQL Server 2016, SQL Server 2017 e Azure SQL DB.

IMPORTANTE: A versão 32 bits da ferramenta foi descontinuada. Ela está disponível agora somente para plataformas 64 bits.

Microsoft SQL Server Migration Assistant v7.6

Baixe o Microsoft SQL Server Migration Assistant v7.6

Download da versão 7.6 para MySQL
Download da versão 7.6 para Access
Download da versão 7.6 para SAP Adaptive Server Enterprise (ex-Sybase)
Download da versão 7.6 para Oracle Database
Download da versão 7.6 para IBM DB2

O Microsoft SQL Server Migration Assistant v7.6 é compatível com o Windows 10, Windows 7, Windows 8, Windows 8.1, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2 e Windows Server 2016. Ele também requer o .NET Framework 4.5.2 ou posterior.

As páginas de download também listam alguns requisitos específicos, como MySQL Connector/ODBC e SAP ASE OLEDB/ADO.Net/ODBC provider.

Fontes e Direitos Autorais: Microsoft.com – https://www.microsoft.com/en-us/download/details.aspx?id=54258&WT.mc_id=rss_alldownloads_all – 25/09/2017.

Publicado em Azure, Backup, Banco de Dados, Banco de Dados, Cloud Computing, Correções, Curiosidades, DBA, Desenvolvimento, Educação, Ferramentas, Hardware, Inovações, Internet, Interoperabilidade, Linux, Microsoft, MSDN, Mundo SQL Server, Notícias, Segurança, Sistema Operacional, SQL Server, TechNet, TI Verde, Transact-SQL, Utilitários, VIRTUAL PASS BR, Virtualização, Visual Studio, Visual Studio, Windows, Windows Server | Marcado com , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Deixe um comentário

Short Scripts – Setembro 2017


Muito boa tarde!!! Olá galera….

Após mais um sábado de aulas na Fatec São Roque, chegou a hora de se dedicar a comunidade de tecnologia, mais especificamente aos amantes de bancos de dados.

Como promessa é dívida e deve ser cumprida “ou melhor” paga, estou pagando a minha feita a exatos três meses no final do último post da sessão Short Scripts, hoje publicando mais um conjunto de scripts adicionados a minha biblioteca particular de códigos e exemplos nos últimos meses.

O post de hoje

Como de costume selecionei os principais scripts armazenados recentemente na minha biblioteca de códigos, que apresentam os seguintes assuntos:

  • Cálculo de Datas;
  • Comando Select;
  • Computed Column;
  • CTE Recursiva;
  • Formatação de Plano de Contas;
  • Função Format();
  • Função Parse();
  • Operador Cross Apply;
  • Operador Outer Apply;
  • Scalar User Defined Function;
  • Sequência Fibonacci; e
  • Sequência numérica de CEPs.

Chegou a hora, mãos nos teclados, a seguir apresento os códigos e exemplos selecionados para o Short Script – Setembro 2017. Vale ressaltar que todos os scripts publicados nesta sessão foram devidamente testados, mas isso não significa que você pode fazer uso dos mesmo em seu ambiente de produção, vale sim todo cuidado possível para evitar maiores problemas.

Fique a vontade para compartilhar, comentar e melhorar cada um destes códigos.

Short Scripts

— Short Script 1  – Calculando o Ano e Mês posterior através do ano e mês  —

Declare @AnoMes int = 201712

Declare @AnoMesPosteriorDate date = DATEADD(MONTH, @AnoMes % 100, DATEADD(YEAR, @AnoMes / 100 – 1900, 0))

Declare @AnoMesPosterior int = YEAR(@AnoMesPosteriorDate) * 100 + Month(@AnoMesPosteriorDate)

Select @AnoMes, @AnoMesPosterior
Go

— Short Script 2  –  Comando Select especificando o nome da coluna e o valor através do sinal de igual —

Select ‘1/0’ = ‘Hello’, ‘2…’ = ‘teste’
Go

— Short Script 3  – Formatando a apresentação de um Plano de Contas —

DECLARE @tableDados TABLE ( Codigo VARCHAR(100) )

INSERT  INTO @tableDados
        SELECT  ‘1.0.0.0.0.00.00’
        UNION  ALL
        SELECT  ‘1.1.0.0.0.00.00’
        UNION ALL
        SELECT  ‘1.1.1.1.2.00.00’
        UNION ALL
        SELECT  ‘2.3.7.1.1.01.00’
        UNION ALL
        SELECT  ‘2.3.2.0.5.00.00’

SELECT  Codigo FROM @tableDados

SELECT TD.Codigo,  LEFT(TD.CODIGO, LEN(TD.CODIGO) – PATINDEX(‘%[1-9]%’, REVERSE(TD.CODIGO)) + 1)
FROM @tableDados AS TD
Go

— Short Script 4  –  Formatando a apresentação de dados através das funções Parse() e Format() —

Declare @Valor Varchar(10)
Set @Valor=’1,540.20′

Select @Valor As Antes, PARSE(@Valor As money Using ‘en-US’) As Depois

Select FORMAT(Cast(@Valor As Money),’C’,’pt-BR’)
Go

— Short Script 5  – Analisando as diferentes de comportamente entre os operadores Cross Apply e Outer Apply —

Declare @Tabela1 Table
(Codigo Int,
Valor Int)

Declare @Tabela2 Table
(Codigo Int,
Valor Int)

Insert Into @Tabela1 Values (1,1),(2,2),(Null, Null)
Insert Into @Tabela2 Values (1,1),(2,2),(3,3),(4,4),(5,5), (Null, Null)

— Utilizando operador Outer Apply —
Select T.Codigo,
T.Valor
From @Tabela1 T Outer Apply (Select Codigo From @Tabela2
Where Codigo = T.Codigo) As T2

— Utilizando operador Cross Apply —
Select T.Codigo,
T.Valor
From @Tabela1 T Cross Apply (Select Codigo From @Tabela2
Where Codigo = T.Codigo) As T2

— Short Script 6  – Criando a sequência Fibonacci de valores —

Create Table Sequence
(Code Int Primary Key Identity(1,1),
Number BigInt Not Null)
Go

Declare @Counter Int = 1, @String Varchar(Max)

While @Counter <=50
Begin

Insert Into Sequence (Number)
Select IsNull(Sum(Number),1) from Sequence
Where Code < @Counter -1

Set @String = (Select Concat(@String,’,’,Number) from Sequence Where Code = @Counter)

Set @Counter +=1

End

Update Sequence
Set Number = 0
Where Code = 1

Select Number ‘Number List’ From Sequence

Select ‘0’+@String As ‘Sequence Finobacci’
Go

— Short Script 7 –  Criando uma Computed Column para uso de uma Scalar User Defined Function —

— Criando a Function F_CalcularDiferencaAnos —
Create Function F_CalcularDiferencaAnos (@DataNascimento Date)
Returns Int
As
Begin
Return (Select DATEDIFF(Year, @DataNascimento, GetDate()))
End
Go

— Criando a Tabela1 para Teste —
Create Table Tabela1
(Codigo Int,
DataNascimento Date,
DiferencaComputada As (dbo.F_CalcularDiferencaAnos(DataNascimento))) — Criando uma coluna computada com a function —
Go

— Inserindo os dados —
Insert Into Tabela1 (Codigo, DataNascimento)
Values (1,’1980-04-28′), (2,’1981-01-28′)
Go

— Validando o resultado —
Select * from Tabela1
Go

— Short Script 8  –  Criando uma sequência de valores de CEPs através de uma CTE Recursiva —

Declare @Tabela table
(Codigo int, Cidade varchar(40), Inicio char(9), Fim char(9));

insert into @Tabela values (1, ‘Belo Horizonte’, ‘30000-000’, ‘35000-000’)

;With CTE_Rec as
(
Select Cidade,
            Cast(left(Fim, 5) + right(Fim, 3) as int) as Fim,
            Cast(left(Inicio, 5) + right(Inicio, 3) as int) as Cep
From @Tabela

Union all

Select Cidade, Fim, Cep + 1
from CTE_rec
where Cep < Fim
)

Select Cidade, cast(Cep / 1000 as char(5)) + ‘-‘ + right(’00’ + cast(Cep % 1000 as varchar), 3) as Cep,
(Cep / 1000) as Div,
(Cep % 1000) as Div2
from CTE_Rec
OPTION (MAXRECURSION 0)
Go

 

Ufa, chegamos ao final! Mais uma relação de short scripts acaba de ser compartilhada, mesmo sendo denominados short entre aspas “pequenos”, posso garantir que todos estes exemplos são de grande importância, apresentam um valor e conhecimento do mais alto nível.


Chegamos ao final de mais um Short Scripts, espero que este material possa lhe ajudar, ilustrando o uso de alguns recursos e funcionalidades do Microsoft SQL Server.

Acredito que você tenha observado que estes códigos são conhecidos em meu blog, todos estão relacionados aos posts dedicados ao Microsoft SQL Server publicados no decorrer dos últimos anos.

Boa parte deste material é fruto de um trabalho dedicado exclusivamente a colaboração com a comunidade, visando sempre encontrar algo que possa ser a solução de um determinado problema, bem como, a demonstração de como se pode fazer uso de um determinado recurso.

Links

Caso você queira acessar os últimos posts desta sessão, não perca tempo acesse os links listados abaixo:

Agradecimento

Obrigado mais uma vez por sua visita, fico honrado com sua ilustre visita ao meu blog, desejo e espero que você possa ter encontrado algo que lhe ajudou.

Volte sempre, nos encontraremos mais uma vez na sessão Short Scripts no post do mês de dezembro.

Um forte abraço, até mais.

Publicado em Banco de Dados, Banco de Dados, Curiosidades, DBA, Desenvolvimento, Dicas, Diversos, Educação, Ferramentas, Interoperabilidade, Linux, Material de Apoio, Microsoft, MSDN, Mundo SQL Server, Scripts, Short Scripts, Sistema Operacional, SQL Server, TechNet, TI Verde, Transact-SQL, Utilitários, VIRTUAL PASS BR, Virtualização, Visual Studio, Visual Studio, Windows, Windows Server | Marcado com , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Deixe um comentário

Dica do Mês – Simulando a inserção de uma massa de dados aleatória


Olá pessoal, boa tarde.

Estou retornando com mais um post da sessão Dica do Mês, onde hoje vou compartilhar algo que poderá lhe ajudar de maneira simples e direta em suas atividades relacionadas a simulação de manipulação de dados no Microsoft SQL Server.

Acredito que em algum momento você já teve a necessidade de inserir dezenas, centenas ou até mesmo milhares de linhas em uma determinada tabela em seus bancos de dados, se você ainda não passou por esta necessidade pode ter a certeza que em algum momento isso poderá lhe acontecer.

Pensando justamente nisso, vou compartilhar no post de hoje um script de minha autoria que utilizo justamente para realizar esta inserção de dados aleatórios em uma tabela específica sem levar em consideração a qualidade e veracidade dos dados, como também regras de integridade referencial ou normalização.

Sendo assim, seja bem vindo ao post – Dica do Mês – Simulando a inserção de uma massa de dados aleatória.

Bom divertimento……


Introdução

A necessidade de se trabalhar com um volume considerável de dados pode ser algo bastante comum para muitos profissionais de bancos de dados, para outros nem tanto.

Este pode parecer um cenário bastante complexo, que venha a exigir um grande conhecimento técnico ou até mesmo o uso de ferramentas de terceiros para tal finalidade. Mas na sua grande maioria os recursos existentes no próprio Microsoft SQL Server nos permite criar scripts ou blocos de códigos capazes de realizar tão procedimento sem requerer a obtenção ou exigência de um alto nível de conhecimento.

Nosso Cenário

Afim de tentar ilustrar como podemos realizar este tipo de procedimento em um ambiente de banco de dados, vamos trabalhar com um ambiente de banco de dados bastante simples e que apresenta baixa complexidade.

Nosso ambiente será forma por uma única tabela denominada MassaDeDados, composta pela seguinte estrutura de colunas:

  • Codigo;
  • ClienteID;
  • VendedorID;
  • Quantidade;
  • Valor; e
  • Data

A coluna denominada Codigo será definida como nossa coluna chave primária artificial numerada de forma sequência próprio SQL Server, tento como finalidade evitar a duplicação de registros e principalmente ser utilizada como atributo de busca e pesquisa de nossos dados. As demais colunas estarão sendo utilizadas como atributos complementares para ilustrar a capacidade de geração de dados aleatórios e posteriormente inseridos em nossa tabela MassaDeDados.

A seguir apresento o Bloco de Código 1, utilizado para criação da tabela MassaDeDados:

— Bloco de Código 1 —

Create Table MassaDeDados
(Codigo int IDENTITY(1,1) NOT NULL Primary Key,
ClienteId int NOT NULL,
VendedorId varchar(10) NOT NULL,
Quantidade smallint NOT NULL,
Valor numeric(18, 2) NOT NULL,
Data date NOT NULL)
Go

Perfeito, note que este bloco de código é bastante simples, nosso próximo passo será justamente trabalhar com o bloco de código que nos permitirá gerar o volume de dados aleatórios inseridos na sequência dentro da tabela MassaDeDados, para tal procedimentos vamos utilizar o Bloco de Código 2 apresentado abaixo:

— Bloco de Código 2 —

Declare @Texto Char(130), @Posicao TinyInt, @ContadorLinhas Int

Set @Texto = ‘0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyzŽŸ¡ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝàáâãäåæçèéêëìíîïðñòóôõöùúûüýÿ’ — Existem 130 caracteres neste texto —

Set @ContadorLinhas = Rand()*100000 — Definir a quantidade de linhas para serem inseridas —

While (@ContadorLinhas >=1)
Begin

Set @Posicao=Rand()*130

 

If @Posicao <=125
Begin
Insert Into MassaDeDados (ClienteId, VendedorId, Quantidade, Valor, Data)
Values(@ContadorLinhas,
Concat(SubString(@Texto,@Posicao+2,2),SubString(@Texto,@Posicao-4,4),SubString(@Texto,@Posicao+2,4)),
Rand()*1000,
Rand()*100+5,
DATEADD(d, 1000*Rand() ,GetDate()))

End
Else
Begin
Insert Into MassaDeDados (ClienteID, VendedorID, Quantidade, Valor, Data)
Values(@ContadorLinhas,
Concat(SubString(@Texto,@Posicao-10,1),SubString    (@Texto,@Posicao+4,6),SubString(@Texto,@Posicao-12,3)),
Rand()*1000,
Rand()*100+5,
DATEADD(d, 1000*Rand() ,GetDate()))

End

Set @ContadorLinhas = @ContadorLinhas – 1
End

Observação: Note que estou utilizando a função Concat() para realizar a concatenação dos dados sem a necessidade de conversão implícita, sendo esta função recurso adicionado a partir da versão 2012 do SQL Server, caso você esteja utilizando uma versão anterior remova a função Concat() e aplique a concatenação utilizando o operador de soma.

Agora basta executar o bloco de código e verificar o resultado obtido, no meu caso após a execução deste mesmo exemplo obtive o resultado apresentado pela Figura 1 apresentada abaixo:

Figura 1 – Massa de Dados aleatórios inseridos na tabela MassaDeDados.

Observando a Figura 1, torna-se fácil analisar o conjunto de dados aleatórios inseridos em cada coluna de nossa tabela, como também, a quantidade de linhas inseridas sendo um total de 41.857 linhas de registros.

Inicialmente o tamanho do bloco de código poderá parecer complexo ou até mesmo confuso, mas na verdade não é bem assim, o grande segredo esta justamente no uso da variável @Texto que apresenta um conjunto de 130 caracteres que podemos utilizar no processo de geração do nosso volume aleatório de dados.

Outro fator muito importante é o uso da função RAND() que nos possibilidade o sorteio de números decimais, algo que ajuda bastante quando queremos trabalhar com faixas de valores distintos.

Vale ressaltar que a função RAND trabalhar com valores decimais, para que seja possível realizar o sorteio aleatório de números e depois transformar em números inteiros temos a necessidade de utilizar variáveis que trabalhem com tipos de dados inteiros, neste caso: TinyInt, SmallInt, Int ou BigInt, caso contrário os valores retornados por esta função será sempre tratados e apresentados no formato de números decimais.

Com isso chegamos ao final de mais um post da sessão Dica do Mês, espero que você tenha gostado.

Referências

https://technet.microsoft.com/pt-br/library/ms177610(v=sql.105).aspx

https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql

https://docs.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql

https://technet.microsoft.com/pt-br/library/hh231515(v=sql.110).aspx

Posts Anteriores

https://pedrogalvaojunior.wordpress.com/2017/05/23/conhecendo-e-aplicando-o-uso-de-atualizacao-de-estatisticas-incrementais/

https://pedrogalvaojunior.wordpress.com/2017/04/13/dica-do-mes-microsoft-sql-server-identificando-as-transacoes-que-estao-utilizando-o-transact-log/

https://pedrogalvaojunior.wordpress.com/2017/03/01/dica-do-mes-microsoft-sql-server-2016-sp1-novo-argumento-use-hint-disponivel-para-query-hints/

https://pedrogalvaojunior.wordpress.com/2017/01/16/dica-do-mes-conhecendo-a-nova-dmf-sys-dm_exec_input_buffer-no-microsoft-sql-server-2016/

Conclusão

Em diversos cenários temos a necessidade de imaginar diversas possibilidades para se obter a solução de um problema que inicialmente se apresenta com algo de outro mundo, por outro lado realizando uma análise com calma e simulando diversos cenários esta possível solução tão “misteriosa” e “complexa” pode estar na frente de nossos olhos.

No post de hoje isso não foi diferente, realizar a inserção de um volume aleatório e fictício de dados dentro do Microsoft SQL Server pode ser feito de forma bastante simples e prática, sem requerer qualquer tipo ferramentas adicionais ou conhecimento de alto nível.

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Um forte abraço, nos encontramos no próximo post a ser publicado no mês de outubro.

Valeu….

Publicado em Banco de Dados, Banco de Dados, Curiosidades, DBA, Desenvolvimento, Dica do Mês, Dicas, Educação, Interoperabilidade, Linux, Microsoft, MSDN, Mundo SQL Server, Scripts, Sistema Operacional, SQL Server, TechNet, Transact-SQL, Utilitários, VIRTUAL PASS BR, Virtualização, Visual Studio, Windows, Windows Server | Marcado com , , , , , , , , , , , , , , , , , , , | 2 Comentários