Pergunta

Eu tenho uma tabela com um número de campos na mesma. Eu estou tentando criar o filtro de pesquisa no asp.net para que o usuário pode procurar por um ou uma combinação de campos. Então, basicamente, eu quero criar um único procedimento armazenado que leva em 4 params e vai anexar o param para a cláusula WHERE se não for nulo ...

TableExample tem 4 colunas, Col1 Col2 Col3 Col4

Estou esperando há maneira de fazer isso com um único procedimento armazenado em vez de ter que criar um para cada combinação possível.

Eu estava tentando algo parecido com isso, o que não é correto, mas seu o que ive tenho até agora.

OBRIGADO!

CREATE PROCEDURE [dbo].[Search]
    @Col1 int,
    @Col2 int,
    @Col3 int,
    @Col4 int
AS

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SELECT *

FROM
    [dbo].[TestTable]
WHERE
    1=1
    CASE        
        WHEN @Col1 IN NOT NULL
        THEN AND [Col1] = @Col1

        WHEN @Col2 IN NOT NULL
        THEN AND [Col2] = @Col2

        WHEN @Col3 IN NOT NULL
        THEN AND [Col3] = @Col3

        WHEN @Col4 IN NOT NULL
        THEN AND [Col4] = @Col4
    END
Foi útil?

Solução 5

Agradeço a todos por suas respostas. No entanto, eu fiz isso um pouco diferente. Espero que ajude alguém! Aqui está como eu fui sobre isso:

CREATE PROCEDURE [dbo].[TestTable_Search]
    @Col1 int,
    @Col2 uniqueidentifier,
    @Col3 datetime,
    @Col4 datetime
AS

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SELECT *

FROM
    [dbo].[TestTable]
WHERE
    [Col1] = COALESCE(@Col1, Col1) AND
    [Col2] = COALESCE(@Col2, Col2) AND
    [Col3] >= COALESCE(@Col3 + "00:00:00", Col3) AND
    [Col4] <= COALESCE(@Col4 + "23:59:59", Col4)

Outras dicas

Use o fato de que ou curto-circuitos. Eu assumiu -1 não é um valor válido.

CREATE PROCEDURE [dbo].[Search]
    @Col1 int = -1,
    @Col2 int = -1,
    @Col3 int = -1,
    @Col4 int = -1
AS
Begin
SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SELECT *

FROM
    [dbo].[TestTable]
WHERE
 (@Col1 = -1 OR [Col1] = @Col1)
and
(@Col2 = -1 OR [Col2] = @Col2)
and
(@Col3 = -1 OR [Col3] = @Col3)
and
(@Col4 = -1 OR [Col4] = @Col4)



END

Pesquisa é uma das raras opções eu prego usando o SQL dinâmico ou a construção de sua cadeia de SQL no código. se você tem um todo o ambiente sproc sql uso dinâmico em sua sproc. parametrizar-lo e usar sp_executesql para executá-lo para evitar SQL Injection

Você pode fazê-lo com um método semelhante ao que você tem:

WHERE
  CASE
    WHEN @Col1 IS NULL THEN true
    ELSE [Col1] = @Col1
  END
AND
  CASE
    WHEN @Col2 IS NULL THEN true
    ELSE [Col2] = @Col2
  END
...

Ou você pode torná-lo muito mais simples, embora possivelmente menos legível:

WHERE (@Col1 IS NULL OR [Col1] = @Col1])
  AND (@Col2 IS NULL OR [Col2] = @Col2])
  AND ...

Você teria que usar SQL dinâmico para fazê-lo:

CREATE PROCEDURE [dbo].[Search]
    @Col1 int,
    @Col2 int,
    @Col3 int,
    @Col4 int
AS

DECLARE @SQL nvarchar(MAX)

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SET @SQL = 'SELECT * 
              FROM [dbo].[TestTable]
             WHERE 1=1 '

IF @Col1 IS NOT NULL
SET @SQL = @SQL + ' AND Col1 = ''' + @Col1 + ''' '

IF @Col2 IS NOT NULL
SET @SQL = @SQL + ' AND Col2 = ''' + @Col2 + ''' '

IF @Col3 IS NOT NULL
SET @SQL = @SQL + ' AND Col3 = ''' + @Col3 + ''' '

IF @Col4 IS NOT NULL
SET @SQL = @SQL + ' AND Col4 = ''' + @Col4 + ''' '

exec sp_executesql @SQL

END

Tenha em mente que existem perigos para isso, incluindo a injeção de SQL, bem como uma série de outros problemas de permissões que podem surgir, já que é SQL dinâmica, mas é a única maneira de conseguir isso na camada de banco de dados. Se você quer construir você consulta na camada de aplicação (em C #), você pode se defender contra os ataques de injeção SQL muito mais cuidadosamente.

Algumas ligações SQL dinâmica que pode ajudar você a entender as desvantagens:

http://www.sommarskog.se/dynamic_sql.html http: //slashstar.com/blogs/tim/archive/2006/10/12/The-Prevalence-and-Dangers-of-SQL-Injection.aspx

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top