相信有很多开发者和我一样对于参数化查询认识比较模糊,没有引起足够的重视吧!错误认识1.不需要防止sql注入的地方无需参数化参数化查询就是为了防止SQL注入用的,其它还有什么用途不知道、也不关心,原则
相信有很多开发者和我一样对于参数化查询认识比较模糊,没有引起足够的重视吧!
错误认识1. 不需要防止sql注入的地方无需参数化
参数化查询就是为了防止SQL注入用的,其它还有什么用途不知道、也不关心,原则上是能不用参数就不用参数,为啥?多麻烦,我只是做公司内部系统不用担心SQL注入风险,使用参数化查询不是给自己找麻烦,简简单单拼SQL,万事OK
错误认识2. 参数化查询时是否指定参数类型、参数长度没什么区别
下面来看具体测试
首先清空查询计划
传值username1,不指定参数长度,生成查询计划
//传值 username1,不指定参数长度
传值username,指定参数长度为50,生成查询计划
//传值 username,指定参数长度为50 //查询计划为(@UserName varchar(50))select * from Users where UserName=@UserName
传值username1,指定参数长度为50,生成查询计划
//传值 username1,指定参数长度为50 //查询计划为
使用下面语句查看执行的查询计划
WHERE sql LIKE '%Users%' and sql not like '%syscacheobjects%'结果如下图所示

可以看到指定了参数长度的查询可以复用查询计划,而不指定参数长度的查询会根据具体传值而改变查询计划,从而造成性能的损失。
这里的指定参数长度仅指可变长数据类型,主要指varchar,nvarchar,char,nchar等,对于int,bigint,decimal,datetime等定长的值类型来说,无需指定(即便指定了也没有用),详见下面测试,UserID为int类型,无论长度指定为2、20、-1查询计划都完全一样为
//传值 2,参数长度2 //执行计划
//传值 2,参数长度20 //执行计划
//传值 2,参数长度-1 //执行计划
这里提一下,若要传值varchar(max)或nvarchar(max)类型怎么传,其实只要设定长度为-1即可
当然了若是不使用参数化查询,直接拼接SQL,那样就更没有查询计划复用一说了,除非你每次拼的SQL都完全一样
总结,参数化查询意义及注意点
1.可以防止SQL注入
2.可以提高查询性能(主要是可以复用查询计划),这点在数据量较大时尤为重要
3.参数化查询参数类型为可变长度时(varchar,nvarchar,char等)请指定参数类型及长度,若为值类型(int,bigint,decimal,datetime等)则仅指定参数类型即可
4.传值为varchar(max)或者nvarchar(max)时,参数长度指定为-1即可