2010-07-15 146 views
1

我在Windows Server 2008 Enterprise中使用SQL Server 2008 Enterprise。我有一个名为“书”的数据库表,它有很多列和三列在这个问题中很重要,它们是sql select语句问题中的where子句

  • 作者,varchar;
  • Country,varchar;
  • Domain,varchar。

我想用以下逻辑编写存储过程,但我不知道如何编写(因为复杂的查询条件),感谢任何人都可以为我编写样本?

输入参数:p_author为varchar,p_country如varchar和p_domain为varchar

查询条件:

  1. 如果从输入指定p_author,然后其作者柱LIKE任一行%p_author%的满足条件,如果未从输入中指定p_author,则每行都满足此条件;
  2. 如果从输入中指定了p_country,那么任何其Country列= p_country的行都满足条件,如果未从输入中指定p_country,则每行满足此条件;
  3. 如果从输入中指定了p_domain,那么任何其列域LIKE%p_domain%满足的行,如果未从输入中指定p_domain,则每行满足此条件;

结果我想回到(必须满足所有以下条件):

  • 记录会见了任一条件1或2;
  • 记录必须符合条件3;
  • 返回不同的行。

例如,满足条件1和条件3的记录可以返回,满足条件2和条件3的记录可以返回。

由于事先 乔治

+1

查询条件3是否正确表达?从项目符号的角度来看,查询条件3应该是“任何一个行列的LIKE%p_domain%被满足的行” - 即。必须根据第二个项目符号提供p_domain。 – 2010-07-15 17:19:57

+0

原始描述是正确的。但不是很清楚,对不起。 :-) 可以用这种方式描述,如果p_domain从输入中为空,那么p_domain总是满足条件3,因为如果没有从输入中指定p_domain,表中的每一行都满足这个(意味着第3个)条件。 – George2 2010-07-15 17:36:04

回答

1

如果我理解正确的话,下面应该工作:

SELECT * 
FROM Books 
WHERE (
    ((Author LIKE '%' + @p_author + '%' OR @p_author = '') OR 
    (Country LIKE '%' + @p_country + '%' OR @p_country = '')) 
    AND (@p_author <> '' OR @p_country <> '') 
) AND 
(Domain LIKE '%' + @p_domain + '%' OR '%' @p_domain = '') 
+0

如果还有一个必须有条件返回满意的行,我可以在将来的where子句中添加另一个AND语句吗?我不确定有多少AND/OR可以添加到where子句中。 – George2 2010-07-15 17:12:31

+1

您应该可以添加额外的AND语句,只要确保您将所有内容保持在逻辑上嵌套在一起。你不想过度,但它应该是可行的。 – LittleBobbyTables 2010-07-15 17:16:29

+1

你可以添加任意数量的AND,只要你愿意,它并不重要,你永远不会使用索引,你会触摸表中的每一行,无论 – 2010-07-15 17:24:27

2

基于给定参数的动态改变搜索是一个复杂的问题,并做了另一种方式即使只有非常微小的差异,也可能产生巨大的性能影响。关键是要使用索引,忽略紧凑的代码,不要担心重复的代码,你必须制定一个好的查询执行计划(使用索引)。

阅读并考虑所有的方法。你最好的方法将取决于您的参数,你的数据,你的模式,你的实际使用情况:

Dynamic Search Conditions in T-SQL by by Erland Sommarskog

The Curse and Blessings of Dynamic SQL by Erland Sommarskog

如果你有正确的SQL Server 2008的版本(SQL 2008 SP1 CU5(10.0 .2746)和更高版本),您可以使用这个小技巧实际使用索引:

由于您使用的是LIKE,因此您可以做的不多,但如果您使用的是平等,则可以添加OPTION(RECOMPILE )到您的查询上,请参阅Erland的文章,并且SQL Server将解析OR在根据局部变量的运行时间值创建查询计划之前从(Column = @Param+'%' OR @Param='') AND ...以内,并且如果您没有使用LIKE,则可以使用索引。