vb.net - valor - validar que no sea null vb net
¿Manejar los datos en una cláusula IN, con parámetros SQL? (6)
Aquí hay una técnica que uso
ALTER Procedure GetProductsBySearchString
@SearchString varchar(1000),
as
set nocount on
declare @sqlstring varchar(6000)
select @sqlstring = ''set nocount on
select a.productid, count(a.productid) as SumOf, sum(a.relevence) as CountOf
from productkeywords a
where rtrim(ltrim(a.term)) in ('''''' + Replace(@SearchString,'' '', '''''','''''') + '''''')
group by a.productid order by SumOf desc, CountOf desc''
exec(@sqlstring)
Todos sabemos que las declaraciones preparadas son una de las mejores maneras de defenderse de los ataques de inyección SQL. ¿Cuál es la mejor manera de crear una declaración preparada con una cláusula "IN"? ¿Hay una manera fácil de hacer esto con una cantidad no especificada de valores? Tome la siguiente consulta, por ejemplo.
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (1,2,3)
Actualmente estoy usando un bucle sobre mis valores posibles para construir una cadena como.
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (@IDVAL_1,@IDVAL_2,@IDVAL_3)
¿Es posible usar simplemente pasar una matriz como el valor del parámetro de consulta y usar una consulta de la siguiente manera?
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (@IDArray)
En caso de que sea importante, estoy trabajando con SQL Server 2000, en VB.Net
Aquí tienes: primero crea la siguiente función ...
Create Function [dbo].[SeparateValues]
(
@data VARCHAR(MAX),
@delimiter VARCHAR(10)
)
RETURNS @tbldata TABLE(col VARCHAR(10))
As
Begin
DECLARE @pos INT
DECLARE @prevpos INT
SET @pos = 1
SET @prevpos = 0
WHILE @pos > 0
BEGIN
SET @pos = CHARINDEX(@delimiter, @data, @prevpos+1)
if @pos > 0
INSERT INTO @tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(@data, @prevpos+1, @pos-@prevpos-1))))
else
INSERT INTO @tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(@data, @prevpos+1, len(@data)-@prevpos))))
SET @prevpos = @pos
End
RETURN
END
luego usa lo siguiente ...
Declare @CommaSeparated varchar(50)
Set @CommaSeparated = ''112,112,122''
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (select col FROM [SeparateValues](@CommaSeparated, '',''))
Creo que sql server 2008 permitirá las funciones de tabla.
ACTUALIZAR
Exprimirá un poco de rendimiento adicional con la siguiente sintaxis ...
SELECT ID,Column1,Column2 FROM MyTable
Cross Apply [SeparateValues](@CommaSeparated, '','') s
Where MyTable.id = s.col
Porque la sintaxis anterior hace que SQL Server ejecute un comando extra de "Ordenar" usando la cláusula "IN". Además, en mi opinión, se ve mejor: D!
En SQL Server 2008, finalmente lograron resolver este problema clásico al agregar un nuevo tipo de datos "de tabla". Aparentemente, eso le permite pasar una matriz de valores, que pueden usarse en una selección secundaria para lograr lo mismo que una instrucción IN.
Si está utilizando SQL Server 2008, entonces puede investigar eso.
Puede crear una tabla temporal de TempTable con una sola columna VALOR e insertar todas las ID. Entonces podrías hacerlo con una subselección:
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (SELECT VALUE FROM TempTable)
Si desea pasar una matriz, necesitará una función en sql que pueda convertir dicha matriz en una selección secundaria.
Estas funciones son muy comunes, y la mayoría de los sistemas de cosecha propia se aprovechan de ellas.
La mayoría de los ORM comerciales, o más bien profesionales, hacen ins haciendo un conjunto de variables, por lo que si tienes eso funcionando, creo que ese es el método estándar.
Ve con la solución publicada por digiguru. Es una gran solución reutilizable y usamos la misma técnica también. A los nuevos miembros del equipo les encanta, ya que ahorra tiempo y mantiene constantes nuestros procedimientos almacenados. La solución también funciona bien con SQL Reports, ya que los parámetros pasados a los procedimientos almacenados para crear los conjuntos de registros pasan en varchar (8000). Usted simplemente lo conecta y listo.