¿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:
Categoría: Transact SQL
¿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:
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:
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.