Estou criando um procedimento armazenado para fazer uma pesquisa em uma tabela. Eu tenho muitos campos de pesquisa diferentes, todos opcionais. Existe uma maneira de criar um procedimento armazenado que irá lidar com isso? Digamos que eu tenha uma tabela com quatro campos: ID, Nome, Sobrenome e Título. Eu poderia fazer algo assim:
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
Esse tipo de trabalho. No entanto, ignora registros onde Nome, Sobrenome ou Título são NULL. Se o título não for especificado nos parâmetros de pesquisa, quero incluir registros em que o título é NULL - o mesmo para nome e sobrenome. Eu sei que provavelmente poderia fazer isso com SQL dinâmico, mas gostaria de evitar isso.
tsql
optional-parameters
Corey Burnett
fonte
fonte
code
ISNULL (Nome, ') = ISNULL (@FirstName,' ') - isso fará com que cada NULL seja uma string vazia e esses possam ser comparados via eq. operador. Se você deseja obter todo o título se o parâmetro de entrada for nulo, tente algo assim:code
Nome = @FirstName OU @FirstName IS NULL.Respostas:
Alterar dinamicamente as pesquisas com base nos parâmetros fornecidos é um assunto complicado, e fazê-lo de uma maneira sobre a outra, mesmo com uma diferença muito pequena, pode ter implicações enormes no desempenho. A chave é usar um índice, ignorar o código compacto, ignorar a preocupação com a repetição de código, você deve fazer um bom plano de execução de consulta (use um índice).
Leia isso e considere todos os métodos. Seu melhor método dependerá de seus parâmetros, dados, esquema e uso real:
Condições de pesquisa dinâmica em T-SQL por Erland Sommarskog
A maldição e as bênçãos do SQL dinâmico por Erland Sommarskog
Se você possui a versão apropriada do SQL Server 2008 (SQL 2008 SP1 CU5 (10.0.2746) e posterior), poderá usar este pequeno truque para realmente usar um índice:
Adicione
OPTION (RECOMPILE)
à sua consulta, consulte o artigo de Erland , e o SQL Server resolverá issoOR
de dentro(@LastName IS NULL OR LastName= @LastName)
antes que o plano de consulta seja criado com base nos valores de tempo de execução das variáveis locais e um índice possa ser usado.Isso funcionará para qualquer versão do SQL Server (retorne resultados adequados), mas inclua apenas OPTION (RECOMPILE) se você estiver no SQL 2008 SP1 CU5 (10.0.2746) e posterior. A OPTION (RECOMPILE) recompilará sua consulta, apenas a versão listada a recompilará com base nos valores atuais do tempo de execução das variáveis locais, o que fornecerá o melhor desempenho. Se não estiver nessa versão do SQL Server 2008, deixe essa linha desativada.
fonte
A resposta do @KM é boa, mas não segue completamente um de seus primeiros conselhos;
Se você deseja obter o melhor desempenho, deve escrever uma consulta sob medida para cada combinação possível de critérios opcionais. Isso pode parecer extremo, e se você tiver muitos critérios opcionais, poderá ser, mas o desempenho geralmente é uma troca entre esforço e resultados. Na prática, pode haver um conjunto comum de combinações de parâmetros que pode ser direcionado com consultas personalizadas e, em seguida, uma consulta genérica (conforme as outras respostas) para todas as outras combinações.
A vantagem dessa abordagem é que, nos casos mais comuns tratados por consultas personalizadas, a consulta é a mais eficiente possível - não há impacto pelos critérios não fornecidos. Além disso, índices e outros aprimoramentos de desempenho podem ser direcionados para consultas específicas, em vez de tentar satisfazer todas as situações possíveis.
fonte
Você pode fazer no seguinte caso,
no entanto, dependendo dos dados, às vezes é melhor criar uma consulta dinâmica e executá-las.
fonte
Cinco anos atrasado para a festa.
É mencionado nos links fornecidos da resposta aceita, mas acho que merece uma resposta explícita no SO - construindo dinamicamente a consulta com base nos parâmetros fornecidos. Por exemplo:
Configuração
Procedimento
Uso
Prós:
Contras:
Resposta não direta, mas relacionada ao problema, também conhecido como quadro geral
Geralmente, esses procedimentos armazenados de filtragem não flutuam, mas estão sendo chamados de alguma camada de serviço. Isso deixa a opção de afastar a lógica de negócios (filtragem) do SQL para a camada de serviço.
Um exemplo é o uso do LINQ2SQL para gerar a consulta com base nos filtros fornecidos:
Prós:
Contras:
fonte
Estenda sua
WHERE
condição:ou seja, combine casos diferentes com condições booleanas.
fonte
Isso também funciona:
fonte