Tempo de Leitura: 6 minutosFala pessoal!
Tudo certo ?
No post de hoje, vou compartilhar com vocês uma pesquisa que venho fazendo já há algum tempo, sobre os novos recursos do SQL Server a cada versão, com o foco nos desenvolvedores de query e rotinas de banco de dados. Nos ambientes que trabalho, vejo que muitos acabam “reinventando a roda” ou criando funções UDF para realizar determinadas tarefas (as quais sabemos que são péssimos para performance) quando o próprio SQL Server já provê soluções nativas para isso.
Meu objetivo nesse post é ajudar a você, que está utilizando versões antigas do SQL Server, a avaliar quais as vantagens e novos recursos (apenas na visão do desenvolvedor) que você terá acesso ao atualizar seu SQL Server.
A minha ideia inicial era criar um post só com tudo o que foi alterado do 2008 até o 2019, mas após conversar e receber alguns feedbacks de grandes profissionais que eu considero, como o Edvaldo Castro, Nilton Pinheiro, Caio Amante e o Ariel Fernandez, vou, pela primeira vez no blog, iniciar uma série de posts, de modo que o artigo não fique muito grande e cansativo de ler..
Sendo assim, inicio a série “O que mudou no SQL Server X em relação ao T-SQL – Na visão dos Desenvolvedores”, começando pelo SQL Server 2008 e vou divulgando um post para cada versão até chegar no 2019. Após todos os artigos publicados, vou criar um artigo pra centralizar toda essa série.
SQL Server – O que mudou no T-SQL na versão 2008 ?
Novos tipos de dados: date, time, datetime2, datetimeoffset
Visualizar conteúdo
Na versão 2008, o SQL Server nos apresenta novos tipos de dados para tratar com data e hora. Antes do SQL Server 2008, existia o campo DATETIME, mas para trabalhar com horas não existia tipo de dado específico para isso.
Para pegar um campo DATETIME e retornar apenas a parte da data, sem a hora, uma das soluções (e bem comum) era usando a técnica de CFC (Cast, Floor, Cast):

Atualmente, isso é bem mais simples utilizando o tipo DATE:

E vou demonstrar um pouco sobre os outros tipos de dados:

Novos tipos de dados: date, time, datetime2, datetimeoffset.
Tipos de dados no formato de tabelas
Visualizar conteúdo
Recursos disponível desde o SQL Server 2008, agora podemos declarar tipos com estruturas de tabela e utilizar como parâmetros em SP’s e funções, conforme exemplo abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
-- Cria o tipo tpPessoa CREATE TYPE dbo.tpPessoa AS TABLE ( Nome varchar(100), Idade INT, Dt_Nascimento DATE ) GO -- Cria uma procedure que você irá receber como parâmetro uma variável do tipo tpPessoa CREATE PROCEDURE dbo.stpExibe_Pessoa ( @Pessoa tpPessoa READONLY ) AS BEGIN SELECT * FROM @Pessoa END GO -- Instancia uma variável @Variavel_Pessoa, do tipo tpPessoa, popula os dados e executa a SP stpExibe_Pessoa DECLARE @Variavel_Pessoa AS tpPessoa INSERT INTO @Variavel_Pessoa ( Nome, Idade, Dt_Nascimento ) VALUES ( 'Dirceu Resende', 31, '1987-05-28'), ( 'Patrícia', 31, '1987-01-15'), ( 'Letícia', 21, '1997-04-15') EXEC dbo.stpExibe_Pessoa @Pessoa = @Variavel_Pessoa -- tpPessoa |
Resultado:

Para saber mais sobre isso, acesse o post SQL Server – Como passar uma tabela como parâmetro para Stored Procedures e Funções.
Atribuir valores durante a declaração de variáveis
Visualizar conteúdo
A partir do SQL Server 2008, é possível atribuir valores já na declaração de variáveis, facilitando e reduzindo a quantidade de linhas de código necessárias.
Exemplos de uso:

Obs: Essa funcionalidade não é aplicada às variáveis do tipo TEXT, NTEXT e IMAGE.
Agrupamento de dados com GROUPING SETs
Visualizar conteúdo
Um recurso muito bem recebido a partir do SQL Server 2008, é a utilização de GROUPING SETS, CUBE e ROLLUP para criar agrupamentos de dados, totais e sub-totais de forma simples e com poucas alterações na sua query original.
Exemplo de uso – ROLLUP
|
SELECT ISNULL(B.Ds_Categoria, 'Total') AS Ds_Categoria, ISNULL(B.Ds_Produto, 'Subtotal') AS Ds_Produto, COUNT(*) AS Qt_Vendas, SUM(B.Preco) AS Vl_Total FROM #Vendas A JOIN #Produtos B ON A.Cd_Produto = B.Codigo GROUP BY ROLLUP(B.Ds_Categoria, B.Ds_Produto) |

Exemplo de uso – CUBE
|
SELECT ISNULL(CONVERT(VARCHAR(10), MONTH(A.Dt_Venda)), 'Total') AS Mes_Venda, ISNULL(B.Ds_Categoria, 'Subtotal') AS Ds_Categoria, COUNT(*) AS Qt_Vendas, SUM(B.Preco) AS Vl_Total FROM #Vendas A JOIN #Produtos B ON A.Cd_Produto = B.Codigo GROUP BY CUBE(MONTH(A.Dt_Venda), B.Ds_Categoria) |

Exemplo de uso – GROUPING SETS
|
SELECT ISNULL(B.Ds_Produto, 'Total') AS Ds_Produto, ISNULL(B.Ds_Categoria, 'Subtotal') AS Ds_Categoria, COUNT(*) AS Qt_Vendas, SUM(B.Preco) AS Vl_Total FROM #Vendas A JOIN #Produtos B ON A.Cd_Produto = B.Codigo GROUP BY GROUPING SETS(B.Ds_Categoria, B.Ds_Produto) |

Quer saber mais sobre esse recurso? Não deixe de acessar o post SQL Server – Agrupando dados utilizando ROLLUP, CUBE e GROUPING SETS.
Utilização do MERGE para INSERT, DELETE e UPDATE com apenas 1 comando
Visualizar conteúdo
A partir do SQL Server 2008, agora é possível utilizar o comando MERGE para INSERT, DELETE e UPDATE com apenas 1 instrução SQL. Seu funcionamento é simples: Uma ou mais colunas das tabelas envolvidas são consideradas chaves (identificadores) para caso o valor da chave exista na tabela destino, os valores serão atualizados de acordo com a tabela origem. Caso esse identificador não exista, esse registro será inserido na tabela destino.
Exemplo de uso:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
MERGE dbo.Dim_Venda AS Destino USING dbo.Venda AS Origem ON (Origem.Id_Venda = Destino.Id_Venda) -- Registro existe nas 2 tabelas WHEN MATCHED THEN UPDATE SET Destino.Dt_Venda = Origem.Dt_Venda, Destino.Id_Produto = Origem.Id_Produto, Destino.Quantidade = Origem.Quantidade, Destino.Valor = Origem.Valor -- Registro não existe no destino. Vamos inserir. WHEN NOT MATCHED THEN INSERT VALUES(Origem.Id_Venda, Origem.Dt_Venda, Origem.Id_Produto, Origem.Quantidade, Origem.Valor); |
Quer saber mais sobre o comando MERGE e visualizar vários outros exemplos, inclusive com a stpETL_Upsert, que cria os comandos de MERGE automaticamente para você? Não deixe de visitar o meu post SQL Server – Como utilizar o comando MERGE para inserir, atualizar e apagar dados com apenas 1 comando.
Múltiplos INSERT’s com 1 único comando
Visualizar conteúdo
A partir do SQL Server 2008, agora é possível inserir múltiplos valores em 1 único comando de INSERT com VALUES. Embora já era possível fazer isso utilizando INSERT… SELECT, esse recurso ajuda bastante durante o dia a dia.
Exemplo de uso:
|
INSERT INTO contacts VALUES ('John Doe', '425-333-5321'), ('Jane Doe', '206-123-4567'), ('John Smith', '650-434-7869') |
Vale lembrar a quantidade máxima de valores que podem ser inseridos em um único INSERT é de 1.000 registros.
Uso de operadores de atribuição de valores compostos
Visualizar conteúdo
A partir do SQL Server 2008, podemos utilizar operadores de atribuição de valores compostos, que são esses:
- += Adicionar e atribuir valor
- -= Substrair e atribuir valor
- *= Multiplicar e atribuir valor
- /= Dividir e atribuir valor
- %= Modulo e atribuir valor
- &= Bitwise AND e atribuir valor
- ^= Bitwise XOR e atribuir valor
- |= Bitwise OR e atribuir valor
Exemplos de uso:


Tipos de dados Espaciais
Visualizar conteúdo
O SQL Server 2008 introduziu os tipo de dados especiais (spatial datatypes) no SGBD, o que nos permite representar a localização física ou formato de qualquer figura geométrica, utilizando apenas T-SQL. Podemos utilizar esse tipo de dados para representar países, ruas, cidades, etc. Esses tipos de dados são implementados utilizando o .NET Common Language Runtime (CLR).
Exemplo 1:
|
DECLARE @point geometry; SET @point = geometry::STGeomFromText ('POINT (25 18)', 0); SELECT @point.STX, @point.STY |
Resultado

Exemplo 2
|
SELECT geometry::Point(10,10,0).STBuffer(1) UNION ALL SELECT geometry::Point(20,20,0).STBuffer(1) UNION ALL SELECT geometry::Point(25,10,0).STBuffer(1) |
Resultado

Métodos disponíveis:
- STLength
- STStartPoint
- STEndPoint
- STPointN
- STNumPoints
- STIsSimple
- STIsClosed
- STIsRing
Espero que vocês gostem desse tema, da série que estou iniciando e deixem suas dúvidas nos comentários.
Abraço!
Quando preciso manipular parte de expressões data&hora e não há função nativa eu utilizo a fórmula “origem dos tempos”. Por exemplo, para zerar o horário seria assim:
dateadd (day, datediff (day, 0, DataHora), 0)
Ela é útil quando necessitamos de obter, por exemplo, somente o dia e as horas (desprezando minutos e segundo):
dateadd (hour, datediff (hour, 0, DataHora), 0)
Também funciona para obter final do mês, início do mês etc.