Q1:什麼是動態SQL呢?
A1:首先是SQL語句,是根據條件來拼接SQL
Q2:爲什麼要用動態SQL?
A2:因爲在條件WHERE中出現OR會導致不能使用索引,從而使效率差別巨大。
例如:如圖1、2,
圖(1)
圖(2)
Q3:怎麼樣使用動態SQL?
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