0

我有一张有几列的桌子。我想要一个存储过程,如果这些值的参数不为空,它将过滤每个值的 Select * 语句。我是否必须编写一个类似 sql server 字符串或其他内容,如果该参数不为空,只需将参数值附加到字符串?还是有一种更简单的内置机制来处理这类事情?我知道你必须为 Oracle 做字符串的事情。但是 ms sql server 总是让我觉得更加用户友好。我以为我会先检查一下,然后再潜入。

谢谢

4

1 回答 1

5

The easy route, assuming col is not nullable, or it is and you don't want NULL rows to match:

WHERE col LIKE COALESCE(@param, col)
-- or the longer version:
WHERE (col LIKE @param OR @param IS NULL)

(Where @param is either NULL or something like '%asdf%'.)

If col is nullable and you do want NULL rows to match, you could try this:

WHERE COALESCE(col, 'x') LIKE COALESCE(@param, col, 'x')

There are other ways to do it, as this could potentially lead to bad plans based on your parameterization settings and what parameters are used the first time it is cached (this can lead to poor plan choice due to "parameter sniffing"), but that is probably largely irrelevant here because your WHERE clause is going to force a table scan anyway.

A common alternative when plan quality becomes an issue is to use dynamic SQL, e.g.

DECLARE @sql NVARCHAR(MAX) = N'SELECT ... FROM ... WHERE 1 = 1';

IF @param IS NOT NULL
BEGIN
  SET @sql += ' AND col LIKE ''' + REPLACE(@param, '''', '''''') + '%''';
END

It can be helpful in cases like this to make sure the optimize for ad hoc workloads setting is enabled.

For information on parameter sniffing and dynamic SQL, see these posts by Erland Sommarskog:

http://www.sommarskog.se/query-plan-mysteries.html
http://www.sommarskog.se/dynamic_sql.html

于 2013-01-22T15:00:47.640 回答