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 行数很少(或没有索引)的性能 - 它基本上具有与动态查询相同的性能。
我想知道我们有哪些选项不能进行动态查询。
例如:
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 行数很少(或没有索引)的性能 - 它基本上具有与动态查询相同的性能。