Sql Server参数化查询
来源:广州中睿信息技术有限公司
发布时间:2012/10/21 23:25:16 编辑:itlead 阅读 2501

  相信有很多开发者和我一样对于参数化查询认识比较模糊,没有引起足够的重视吧!

  错误认识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%'结果如下图所示

  1.jpg

  可以看到指定了参数长度的查询可以复用查询计划,而不指定参数长度的查询会根据具体传值而改变查询计划,从而造成性能的损失。

  这里的指定参数长度仅指可变长数据类型,主要指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即可