¡Hola, chicos!
¿Todo muy bien?

En la publicación de hoy, voy a compartir con ustedes una investigación que he estado haciendo desde hace algún tiempo sobre las nuevas características de SQL Server en cada versión, con un enfoque en los desarrolladores de consultas y las rutinas de bases de datos. En los entornos en los que trabajo veo que muchos acaban “reinventando la rueda” o creando funciones UDF para realizar determinadas tareas (que sabemos que son pésimas para el rendimiento) cuando el propio SQL Server ya proporciona soluciones nativas para esto.

Mi objetivo en esta publicación es ayudarlo a usted, que está utilizando versiones antiguas de SQL Server, a evaluar las ventajas y nuevas características (solo desde la perspectiva del desarrollador) a las que tendrá acceso al actualizar su SQL Server.

Mi idea inicial era crear un post solo con todo lo que cambió del 2008 al 2019, pero después de hablar y recibir feedback de grandes profesionales que considero, como Edvaldo Castro, Nilton Pinheiro, Caio Amante y el Ariel Fernández, por primera vez en el blog, voy a iniciar una serie de posts, para que el artículo no se haga demasiado largo y cansado de leer.

Por eso, comienzo la serie “¿Qué cambió en SQL Server?”

SQL Server: ¿Qué cambió en T-SQL en la versión 2008?

Nuevos tipos de datos: fecha, hora, fechahora2, fechahoraoffset

Ver contenido
En la versión 2008, SQL Server nos presenta nuevos tipos de datos para tratar la fecha y la hora. Antes de SQL Server 2008 existía el campo DATETIME, pero para trabajar con horas no existía un tipo de dato específico para eso.

Para tomar un campo DATETIME y devolver sólo la parte de la fecha, sin la hora, una de las soluciones (y muy común) era utilizar la técnica CFC (Cast, Floor, Cast):

Actualmente, esto es mucho más sencillo usando el tipo FECHA:

Y les demostraré un poco sobre los otros tipos de datos:

Nuevos tipos de datos: fecha, equipo, fechahora2, compensación de fecha y hora.

Tipos de datos en formato de tabla

Ver contenido
Funciones disponibles desde SQL Server 2008, ahora podemos declarar tipos con estructuras de tablas y usarlos como parámetros en SP y funciones, como se muestra en el siguiente ejemplo:
-- 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 obtener más información sobre esto, visita la publicación. SQL Server: cómo pasar una tabla como parámetro a funciones y procedimientos almacenados.

Asignar valores durante la declaración de variables

Ver contenido
A partir de SQL Server 2008, es posible asignar valores que ya están en la declaración de variables, haciéndolo más fácil y reduciendo la cantidad de líneas de código necesarias.

Ejemplos de uso:

Nota: Esta funcionalidad no se aplica a variables de tipo TEXTO, NTEXTO e IMAGEN.

Agrupar datos con GROUPING SETs

Ver contenido
Una característica muy bien recibida de SQL Server 2008 es el uso de GROUPING SETS, CUBE y ROLLUP para crear agrupaciones de datos, totales y subtotales de una manera sencilla y con pocos cambios a su consulta original.

Ejemplo 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)

Ejemplo de uso – CUBO

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)

Ejemplo de uso: CONJUNTOS DE AGRUPACIÓN

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)

¿Quieres saber más sobre esta función? No olvides acceder al post. SQL Server: agrupación de datos mediante ROLLUP, CUBE y GROUPING SETS.

Usando MERGE para INSERTAR, ELIMINAR y ACTUALIZAR con solo 1 comando

Ver contenido
A partir de SQL Server 2008, ahora es posible utilizar el comando FUSIONAR para INSERTAR, ELIMINAR y ACTUALIZAR con solo 1 instrucción SQL. Su funcionamiento es sencillo: Una o más columnas de las tablas involucradas se consideran claves (identificadores) por lo que si el valor de la clave existe en la tabla de destino, los valores se actualizarán según la tabla de origen. Si este identificador no existe, este registro se insertará en la tabla de destino.

Ejemplo 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);

¿Quiere saber más sobre el comando MERGE y ver otros ejemplos, incluido stpETL_Upsert, que crea automáticamente comandos MERGE? No olvides visitar mi publicación. SQL Server: cómo utilizar el comando MERGE para insertar, actualizar y eliminar datos con solo 1 comando.

Múltiples INSERT con 1 solo comando

Ver contenido
A partir de SQL Server 2008, ahora es posible insertar múltiples valores en un solo comando INSERT con VALUES. Aunque ya era posible hacer esto usando INSERT… SELECT, esta característica ayuda mucho en la vida cotidiana.

Ejemplo de uso:

INSERT INTO contacts 
VALUES 
    ('John Doe', '425-333-5321'), 
    ('Jane Doe', '206-123-4567'), 
    ('John Smith', '650-434-7869')

Vale recordar que el número máximo de valores que se pueden insertar en un solo INSERT es de 1.000 registros.

Usar operadores de asignación de valor compuesto

Ver contenido
A partir de SQL Server 2008, podemos utilizar operadores para asignar valores compuestos, que son estos:
  • += Agregar y asignar valor
  • -= Restar y asignar valor
  • *= Multiplicar y asignar valor
  • /= Dividir y asignar valor
  • %= Módulo y asignar valor
  • &= bit a bit AND y asignar valor
  • ^= XOR bit a bit y asignar valor
  • |= Bit a bit OR y asignar valor

Ejemplos de uso:

Tipos de datos espaciales

Ver contenido
SQL Server 2008 introdujo tipos de datos especiales (tipos de datos espaciales) en el DBMS, lo que nos permite representar la ubicación física o la forma de cualquier figura geométrica, utilizando únicamente T-SQL. Podemos utilizar este tipo de datos para representar países, calles, ciudades, etc. Estos tipos de datos se implementan utilizando .NET Common Language Runtime (CLR).

Ejemplo 1:

DECLARE @point geometry;
SET @point = geometry::STGeomFromText ('POINT (25 18)', 0);

SELECT 
    @point.STX, @point.STY

Resultado

Ejemplo 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 disponibles:

  • STLongitud
  • STInicioPunto
  • STEndPoint
  • STPointN
  • STNumPuntos
  • ITSSimple
  • ITSCerrado
  • Anillo de ITS

Espero que les guste este tema, la serie que estoy empezando y dejen sus preguntas en los comentarios.
¡Abrazo!