Experimentando con indices en SQL Server – En vivo

¿Cual es la diferencia de utilizar o no utilizar indices en nuestras tablas? Experimento con unas consultas para ver el rendimiento de utilizarlos y no utilizarlos:

¿Cómo crear una función en transact-sql que reciba una cadena con los ids para aplicaros con la función In de sql?

Para esto necesitaremos crear la función mítica Split de sql que tiene años en internet y pongo a continuación (desconozco el autor):

CREATE FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20) = ' ')
RETURNS @Strings TABLE
(
  position int IDENTITY PRIMARY KEY,
  value varchar(8000)
)
AS
BEGIN

DECLARE @index int
SET @index = -1

WHILE (LEN(@text) > 0)
  BEGIN
    SET @index = CHARINDEX(@delimiter , @text)
    IF (@index = 0) AND (LEN(@text) > 0)
      BEGIN
        INSERT INTO @Strings VALUES (@text)
          BREAK
      END
    IF (@index > 1)
      BEGIN
        INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
        SET @text = RIGHT(@text, (LEN(@text) - @index))
      END
    ELSE
      SET @text = RIGHT(@text, (LEN(@text) - @index))
    END
  RETURN
END

Una vez con la función Split agregada a nuestra base de datos de la siguiente manera podemos aplicar una cadena que contenga ids y aplicarles alguna modificación a los registros dentro dicha cadena, por ejemplo una procedimiento que modifique un campo(o varios) en común de varios registros recibiendo una cadena con los ids:

CREATE FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20) = ' ')
RETURNS @Strings TABLE
(
  position int IDENTITY PRIMARY KEY,
  value varchar(8000)
)
AS
BEGIN

DECLARE @index int
SET @index = -1

WHILE (LEN(@text) > 0)
  BEGIN
    SET @index = CHARINDEX(@delimiter , @text)
    IF (@index = 0) AND (LEN(@text) > 0)
      BEGIN
        INSERT INTO @Strings VALUES (@text)
          BREAK
      END
    IF (@index > 1)
      BEGIN
        INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
        SET @text = RIGHT(@text, (LEN(@text) - @index))
      END
    ELSE
      SET @text = RIGHT(@text, (LEN(@text) - @index))
    END
  RETURN
END

Y así la mandaríamos llamar:


EXEC sp_algo '1,3,5,7,77,65,666','leviathan'

Esto es útil y rápido cuando se desea modificar masivamente una colección de registros (por ejemplo desde un backend con entity framework) los cuales tendrán el mismo valor en uno de sus campos, solo tomar precauciones con SQL INJECTION (es 2017 y si aún existe)

¿Cómo reiniciar a 0 la clave primaria en sql server cuando es autoincrementable?

Para reiniciar una clave primaria la cual es autoincrementable, o si deseamos poner que nuestro valor continué en un numero en especifico, se realiza de la siguiente manera:


DBCC CHECKIDENT ('esquema.nombretabla', RESEED, 0);

El anterior código pondrá nuestro contador en 0, siendo el siguiente registro a insertarse 1.

Ejecutar una cadena como consulta en SQL Server #SQLServer

Para ejecutar una cadena en Transact-SQL como una consulta, existe el procedure de nombre sp_sqlexec, este recibe la cadena la cual ejecuta. Esto nos sirve para consultas dinámicas pero no es recomendable a menos que se tenga bien planteada la seguridad para evitar travesuras de los “hackers”.

Ejemplo:

declare @cadena varchar(max)='select * from tabla'

exec sp_sqlexec @cadena

Group_concat en #SQLServer, concatenar campos de un agrupamiento como en #mysql.

En este artículo explico cómo realizar una concatenación de un campo de una agrupación en SQL Server (algo parecido a lo que se obtiene con la función group_concat de mysql). Esto sirve para obtener en un registro todos los campos distintos de dicha agrupación. Por ejemplo, tenemos la siguiente tabla de nombre EstadoMunicipio:

tabla sql server - estados municipios

Suponiendo que deseamos agrupar los estados y obtener en un campo al lado la concatenación de sus municipios, eso en mysql se hace con una función llamada group_concat, en SQL Server no existiendo dicha función (que nos facilita todo) podemos obtener el mismo resultado utilizando la función Stuff de Sql Server, pero de una manera especial, como planteo en el siguiente query:

SELECT 
     Estado,
     STUFF(
         (SELECT  municipio +', ' 
          FROM EstadoMunicipio
          WHERE estado = a.estado
          FOR XML PATH (''))
          , 1, 0, '')  AS [Municipios Concatenados]
FROM EstadoMunicipio AS a
GROUP BY Estado

Este es el resultado:

resultado query group_concat sql server

De esa manera podemos realizar algo como lo que hace la función group_concat de mysql.

Si desean utilizar este query, basta con que sustituyan el nombre de la tabla EstadoMunicipio por el nombre de la que tengan ustedes, sustituyan también el nombre del campo municipio, el nombre del campo estado (que es el que utilizamos para agrupar) y la unión realizada en el where, por el campo por el cual están agrupando.