Digamos que tiene un procedimiento almacenado y toma un parámetro opcional. Desea utilizar este parámetro opcional en la consulta SQL. Normalmente, esto es como he visto hacer:¿Manera correcta de manejar los filtros cláusula 'opcional' en SQL?
SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = 'test'
AND (@MyOptionalParam IS NULL OR t1.MyField = @MyOptionalParam)
Esto parece funcionar bien, sin embargo, provoca una alta cantidad de lecturas lógicas si se ejecuta la consulta con STATISTICS IO ON. También probé la siguiente variante:
SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = 'test'
AND t1.MyField = CASE WHEN @MyOptionalParam IS NULL THEN t1.MyField ELSE @MyOptionalParam END
Y produce el mismo número de lecturas altas. Si convertimos el SQL en una cadena, a continuación, llamar Sp_executesql en él, las lecturas son casi nulas:
DECLARE @sql nvarchar(max)
SELECT @sql = 'SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = ''test'''
IF @MyOptionalParam IS NOT NULL
BEGIN
SELECT @sql = @sql + ' AND t1.MyField = @MyOptionalParam '
END
EXECUTE sp_ExecuteSQL @sql, N'@MyOptionalParam', @MyOptionalParam
¿Estoy loco? ¿Por qué son cláusulas opcionales en las que es difícil encontrar la verdad?
Actualización: Básicamente, estoy preguntando si hay una manera de mantener la sintaxis estándar dentro de un procedimiento almacenado y obtener bajas lecturas lógicas, como lo hace el método sp_ExecuteSql. Me parece completamente loco construir una cadena ... sin mencionar que hace que sea más difícil de mantener, depurar, visualizar ...
Nicholas, consulte el enfoque de unión a continuación para conocer la sintaxis estándar de sql sin sql dinámico. Tengo mucha curiosidad de ver que publique cómo funciona en su escenario ... – chadhoc
@Nicholas: construyendo una consulta como una cadena antes de ejecutarla es ** exactamente ** qué SQL * dinámico *. Es un problema menor depurar, copiar y pegar, deshacerse de la sintaxis de concatenación de cadenas. –