日期:2014-05-18  浏览次数:20384 次

关于存储过程及参数化SQL的漏洞-请高手不吝赐教
create procedure [dbo].[test] 
@v int
as
select * from t where name >= @v 

表结构如下:
CREATE TABLE [dbo].[t](
[ID] [int] IDENTITY(1,1) NOT NULL,
[name] [int] NOT NULL,
[c1] [varchar](500) NULL,
[c2] [varchar](110) NULL,
[c3] [varchar](150) NULL,
 CONSTRAINT [PK_t1] PRIMARY KEY CLUSTERED 
(
[ID] ASC
))
PK_t1为聚集索引
在列name上建有非聚集索引ix_name

name的值在1-200之间,如果调用存储过程传入的值@v大于150,应该用索引ix_name比较好,如果小于150用PK_t1较好。但调用的时候无论传入的是什么值,调用的计划都按上第一次的生产的执行计划。那也就是说存储过程的执行编译好了就不会改变其执行计划。不会生产多个执行计划,然后再根据条件去判断选用哪个。
参数化SQL也有类似的情况。
除非是动态SQL或强制with recompile(这样完全没必要了)。

那如果这个层面来讲,存储过程就很大的局限性了。

------解决方案--------------------
'name如果小于150用PK_t1较好'这是为什么 ?
------解决方案--------------------
走哪个索引是根据你where后面的谓词去选择的吧?貌似你可以砸着两个字段上建立一个复合索引

create clustered index ix_name_PK_t1_inx on [dbo].[t](name,ID)