SQL 替代动态查询的服务器

SQL Server alternative to dynamic query

我想知道我们有哪些选项不能进行动态查询。

例如:

IF @Mail <> ''
BEGIN
    SELECT @Where = @Where + ' AND Mail =  @Mail '
END
ELSE IF @Phone <> ''
BEGIN
    SELECT @Where = @Where + ' AND Phone like ''%'' + @Phone '
END

我不想这样做,如果有人能帮助我,我想避免动态查询。

顺便说一下,我想按 Mail 进行过滤,但如果 Mail 不存在,那么我必须按 Phone 进行过滤,但绝不会同时进行过滤。

就性能而言,动态查询可能会更好。更简单的查询通常更容易优化。

然而,您可以将 where 子句表述为:

where . . . AND
      (@Mail = '' or mail = @mail) AND
      (@Phone = '' or Phone like '%' + @Phone)

注意:NULL 值被用来表示 "all" 是很常见的。所以更典型的公式是:

WHERE . . . AND
      (@Mail IS NULL or mail = @mail) AND
      (@Phone IS NULL or Phone like '%' + @Phone)

为什么不使用 CASE WHEN。

这里是 URL 可以帮助您进行此查询。

"CASE" statement within "WHERE" clause in SQL Server 2008

对于多个过滤器,动态 SQL 很有可能表现得更好,因为 OR 和性能通常在 SQL 查询中不协调。

但是,如果过滤器在 "no filter value" 上为 NULL,查询可以这样写:

SELECT Mail, Phone, <other columns here>
FROM table
WHERE Mail = COALESCE(@Mail, Mail)
   AND Phone LIKE (COALESCE('%' + @Phone, Phone)

所有 '' 值都可以使用 nullif(@Mail, '') 轻松转换为 NULL。此外,这将同等对待 ''NULL

你可以试试这个

AND ((ISNULL(@Mail,'') = '' or mail = @mail) OR (ISNULL(@Phone,'') = '' or Phone like '%' + @Phone))

如果您追求性能,最好的解决方案是对每种情况进行单独查询。

Gordon 的解决方案很好,但是 SQL 服务器不会使用您可能希望在过滤所依据的列上使用的任何索引。 可以通过添加 OPTION(RECOMPILE) 来增强使用索引,但这将导致每次查询 运行 时重新编译查询。如果您的 table 有很多行(并且您在列上定义索引),它将显着提高性能,但会降低 table 行数很少(或没有索引)的性能 - 它基本上具有与动态查询相同的性能。