Estoy creando un procedimiento almacenado para hacer una búsqueda en una tabla. Tengo muchos campos de búsqueda diferentes, todos los cuales son opcionales. ¿Hay alguna manera de crear un procedimiento almacenado que se encargue de esto? Digamos que tengo una tabla con cuatro campos: ID, Nombre, Apellido y Título. Podría hacer algo como esto:
CREATE PROCEDURE spDoSearch
@FirstName varchar(25) = null,
@LastName varchar(25) = null,
@Title varchar(25) = null
AS
BEGIN
SELECT ID, FirstName, LastName, Title
FROM tblUsers
WHERE
FirstName = ISNULL(@FirstName, FirstName) AND
LastName = ISNULL(@LastName, LastName) AND
Title = ISNULL(@Title, Title)
END
Este tipo de trabajos. Sin embargo, ignora los registros donde FirstName, LastName o Title son NULL. Si el Título no se especifica en los parámetros de búsqueda, quiero incluir registros donde el Título sea NULO, lo mismo para FirstName y LastName. Sé que probablemente podría hacer esto con SQL dinámico, pero me gustaría evitarlo.
tsql
optional-parameters
Corey Burnett
fuente
fuente
code
where : ISNULL (FirstName, ') = ISNULL (@FirstName,' '): esto hará que cada NULL sea una cadena vacía y se puedan comparar a través de la ecuación. operador. Si desea obtener todo el título si el parámetro de entrada es nulo, intente algo como eso:code
FirstName = @FirstName O @FirstName IS NULL.Respuestas:
Cambiar dinámicamente las búsquedas basadas en los parámetros dados es un tema complicado y hacerlo de una manera sobre otra, incluso con solo una ligera diferencia, puede tener implicaciones masivas de rendimiento. La clave es usar un índice, ignorar el código compacto, ignorar la preocupación de repetir el código, debe hacer un buen plan de ejecución de consultas (use un índice).
Lea esto y considere todos los métodos. Su mejor método dependerá de sus parámetros, sus datos, su esquema y su uso real:
Condiciones de búsqueda dinámica en T-SQL por Erland Sommarskog
La maldición y las bendiciones del SQL dinámico por Erland Sommarskog
Si tiene la versión adecuada de SQL Server 2008 (SQL 2008 SP1 CU5 (10.0.2746) y posterior), puede usar este pequeño truco para usar un índice:
Agregue
OPTION (RECOMPILE)
a su consulta, vea el artículo de Erland , y SQL Server resolveráOR
desde dentro(@LastName IS NULL OR LastName= @LastName)
antes de que se cree el plan de consulta basado en los valores de tiempo de ejecución de las variables locales, y se puede usar un índice.Esto funcionará para cualquier versión de SQL Server (devolver los resultados correctos), pero solo incluye la OPCIÓN (RECOMPILAR) si está en SQL 2008 SP1 CU5 (10.0.2746) y posterior. La OPCIÓN (RECOMPILAR) volverá a compilar su consulta, solo la versión enumerada la volverá a compilar según los valores actuales de tiempo de ejecución de las variables locales, lo que le brindará el mejor rendimiento. Si no está en esa versión de SQL Server 2008, simplemente deje esa línea apagada.
fuente
La respuesta de @KM es buena en la medida de lo posible, pero no puede seguir completamente uno de sus primeros consejos;
Si desea lograr el mejor rendimiento, debe escribir una consulta a medida para cada combinación posible de criterios opcionales. Esto puede sonar extremo, y si tiene muchos criterios opcionales, podría serlo, pero el rendimiento a menudo es una compensación entre el esfuerzo y los resultados. En la práctica, puede haber un conjunto común de combinaciones de parámetros que pueden orientarse con consultas a medida, luego una consulta genérica (según las otras respuestas) para todas las demás combinaciones.
La ventaja de este enfoque es que, en los casos comunes manejados por consultas a medida, la consulta es tan eficiente como puede ser, no hay impacto por los criterios no suministrados. Además, los índices y otras mejoras de rendimiento pueden dirigirse a consultas específicas a medida en lugar de tratar de satisfacer todas las situaciones posibles.
fuente
Puedes hacer en el siguiente caso,
Sin embargo, depender de los datos a veces es mejor crear consultas dinámicas y ejecutarlas.
fuente
Cinco años tarde a la fiesta.
Se menciona en los enlaces proporcionados de la respuesta aceptada, pero creo que merece una respuesta explícita en SO, generando dinámicamente la consulta en función de los parámetros proporcionados. P.ej:
Preparar
Procedimiento
Uso
Pros:
Contras:
No es una respuesta directa, pero está relacionada con el problema, también conocido como panorama general.
Por lo general, estos procedimientos almacenados de filtrado no flotan, sino que se llaman desde alguna capa de servicio. Esto deja la opción de alejar la lógica de negocios (filtrado) de SQL a la capa de servicio.
Un ejemplo es usar LINQ2SQL para generar la consulta basada en los filtros proporcionados:
Pros:
Contras:
fuente
Extiende tu
WHERE
condición:es decir, combinar diferentes casos con condiciones booleanas.
fuente
Esto también funciona:
fuente