Fala 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:
-- 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:

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!