A1:首先是SQL语句,是根据条件来拼接SQL
A2:因为在条件WHERE中出现OR会导致不能使用索引,从而使效率差别巨大。
例如:如图1、2,
图(1)
图(2)
A3:
存储过程Proc_Test是没有采用拼接的:
CREATE PROC Proc_Test ( @姓名 varchar(10), @课程 varchar(10), @分数 int, @总数 int output ) AS BEGIN --取总数 SELECT @总数=COUNT(1) FROM test WHERE (@姓名=‘‘ or 姓名=@姓名) AND (@课程=‘‘ or 课程=@课程) AND (@分数=‘‘ or 分数>=@分数) --取数据 SELECT * FROM test WHERE (@姓名=‘‘ or 姓名=@姓名) AND (@课程=‘‘ or 课程=@课程) AND (@分数=0 or 分数>=@分数) END
拼接后可以改成Proc_Test1
CREATE PROC Proc_Test1 ( @姓名 varchar(10), @课程 varchar(10), @分数 int, @总数 int output ) AS BEGIN declare @sqls1 nvarchar(max) declare @sqls2 nvarchar(max) declare @sqls3 nvarchar(max) set @sqls1=‘ FROM test WHERE ID>1‘/*如果没有一定成立的条件就需要加1=1*/ IF @姓名<>‘‘/*参数过滤*/ BEGIN SET @sqls1=@sqls1+‘ AND 姓名=‘‘‘+@姓名+‘‘‘‘/*AND前面要加空格*/ END IF @课程<>‘‘ BEGIN SET @sqls1=@sqls1+‘ AND 课程=‘‘‘+@课程+‘‘‘‘/*为了@课程加上引号,特别处理。三个引号:其中一个为引号,用于字符串表示,另外两个为引号的转义字符。*/ END IF @分数>0 BEGIN SET @sqls1=@sqls1+‘ AND 分数>=‘+cast(@分数 as nvarchar)/*非字符串参数要转换为字符串*/ END --取总数 SET @sqls2=‘ SELECT @总数=COUNT(1)‘+@sqls1 --取数据 SET @sqls3=‘ SELECT * ‘+@sqls1 exec sp_executesql @sqls2,N‘@总数 int out‘,@总数 out/*语句前的N必不可少*/ exec (@sqls3) END
执行计划:
EXEC Proc_Test ‘‘,‘‘,0,0 EXEC Proc_Test1 ‘‘,‘‘,0,0
本文出自 “sukun” 博客,请务必保留此出处http://sukunwu.blog.51cto.com/10453116/1695774
原文地址:http://sukunwu.blog.51cto.com/10453116/1695774