Separando parámetros en SQL
De vez en cuando se requiere que algún listado reciba parámetros flexibles que permitan seleccionar varios registros por la misma columna, en estos casos podríamos o bien colocar tantas entradas como queramos y pasar un número x de parámetros (que en la mayoria de los casos estaran vacios) o hacer algo para que la cantidad de valores pueda ser dinámicamente definido en el momento en que el usuario entra los valores que desea en el listado.
Para esto hay una solución bastante sencilla de implementar y que da buenos resultados. La solución se logra definiendo un único parámetro de tipo cadena de caracteres donde se colocan los valores separados por un caracter (o cadena) predefinido, con esta entrada construimos una tabla y podemos hacer un inner join y filtrar los registros de manera efectiva.
A continuación un ejemplo de como se puede lograr esto:
/*
Creado por: SmokedIronMade
2007.04.05
Divide una cadena con múltiples entradas en una fila por cada entrada y se devuelve una
tabla con la que es posible filtrar los registros.
*/
alter function [dbo].[Split] ( @Cadena nvarchar(max), @Separador nvarchar(max) )
returns @Tabla table ( Valor nvarchar(max) )
as
begin
declare @Posicion int
declare @Valor nvarchar(max)
while len( ltrim( rtrim( @Cadena ) ) ) > 0
begin
select @Posicion = charindex( @Separador, @Cadena, 0 )
--* si se ha encontrado un separador entonces esto significa que hay más valores
--* en este case tomamos el primero y continuamos procesando el resto
if @Posicion > 0
begin
set @Valor = ltrim( rtrim( left( @Cadena, @Posicion - 1 ) ) )
set @Cadena = reverse( left( reverse( @Cadena ), len( @Cadena ) - @Posicion ) )
end
else --* this is the last token in string
begin
set @Valor = @Cadena
set @Cadena = ''
end
--* add tokens to temporary table
insert into @Tabla ( Valor ) values ( @Valor )
end
return
end
Luego podemos incluirlo en nuestras consultas, como en el siguiente ejemplo:
declare @Cuentas nvarchar(max)
declare @Separador nvarchar(max)
--* estas son las cuentas que queremos ver
set @Cuentas = 'AW%1435,AW%2436%,AW%3437,AW%4442,AW%5445'
--* nuestro separador de valores
set @Separador = ','
select
C.*
from
[AdventureWorks].[Sales].[Customer] C
--* las cuentas en una tabla para filtrar fácilmente los valores
inner join dbo.Split( @Cuentas, @Separador ) S
on ( C.AccountNumber like S.Valor )
La variable @Cuentas hace las veces de parámetro en el cual se han incluidos las cuentas que queremos sean incluidas en los resultados, luego haciendo join de la data con nuestra función obtenemos los resultados deseados de manera sencilla.
Comentarios