参数化查询的理解

一般防护sql 都会出现pdo ,之前也一直不太清楚为什么pdo 能防护sql 注入漏洞,下边这篇博客说的很好,主要是先用参数代替,等到编译完成把参数带入,就不会出现sql 编译解析的问题了。

       机房重构敲组合查询时,会遇到多个操作符(+、-、*、/),因为之前在使用参数化查询时只要遇到给数据库赋值时就使用参数,(光知道这样能防止SQL注入,直到如今才知道它为什么能防止SQL注入)索性就把操作符也用成参数,但这时就报“语法错误”了,可是解决了很长时间,老以为是sql语句写错了(自我认为是那种丢掉一个空格或引号之类的错误),其实是没真正理解之前听到到“防SQL注入”的原理,或是说为什么能“防止SQL注入”


一:参数化查询原理

       参数化查询是指在设计与数据库链接并访问时,在需要数值或数据的地方,使用参数来给值。即在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中有恶意的指令,由于已经编译完成,就不会被数据库运行。目前,参数化查询是最有效可预防SQL注入攻击的的防御方法。(虽为度娘所说,但这几句对我所遇到的问题的理解起到很大帮助和理解)


二:实例解析

       就以我遇到的问题说来,我把“+、-、*、/”作为参数传进SQL语句中,这样是不对的

起初我的SQL语句是这样的,  


报如下错误:

                                           

跟踪到链接数据库之前的sql语句是这样的:

                                           

      而标准的SQL语句是:select 列名 from 表名( where  列名  操作符  查询内容)

而上面跟踪的sql语句中where条件里没有操作符(+、-、*、/)而是一个参数,所以该条SQL语句根本不符合sql语句的语法,即不是一条SQL语句


SQL语句改为:


跟踪到链接数据库之前的SQL语句是:

                                             

结果:

      这样就是一条标准的SQL语句了,所以此问题就这样解决了。(虽然列名还是参数,但只看该条语句是符合SQL语句标准的格式,在实际链接数据库时就给参数赋值了)


三:防SQL注入

       其实参数化查询的作用主要有两点:

              1:参数过滤

              2:执行计划重用

       而防止SQL注入主要就是利用了执行计划重用

       即在链接数据库时给参数赋值时,重用了以前的执行计划,没有对SQL语句重新编译,也就没有重新执行语法解析,所以语句还是原来的结构,符合标准,只是用一个具体的值替换参数。

      其实这个问题的背后隐藏着很多知识:最重要的一条是:SQL SERVER接收到一条sql指令所做的工作:

       简单概括为:收到指令 -> 编译SQL生成执行计划 ->选择执行计划 ->执行执行计划。

       当 Sql Server 收到任何一个指令,包括:查询、批处理、存储过程、触发器、预编译指令和动态SQL Server语句,要完成语法解析、语义分析,然后再进行”编译”,生成能够运行的”执行计划“。在编译的过程中,SQL Server 会根据所涉及的对象的架构、统计信息,以及指令的具体内容,估算可能的执行计划,以及它们的成本,最后选择一个SQL Server认为成本最低的语句。

      执行计划生成之后,SQL Server 通常会把它们缓存到内存里,术语统称它们叫“Plane Cache”。以后同样的语句执行,SQL Server就可以使用同样的执行计划,而无须再做一次编译。这种行为,叫做“重用”。但是有时候,哪怕是一模一样的语句,SQL Server 下次执行还是要再做一次编译。这种行为叫“重编译”。执行计划的编译和重编译都是要耗费资源的。

详细讲解:http://blog.csdn.net/babauyang/article/details/7714211


四:总结

      每个问题的的背后可能会有好多知识点,这些知识点不一定要都吃透,但要明白问题的根源,这样遇到同样原理的问题时才能在节省时间的前提下保质的解决问题,否则虽说此问题解决了,但遇到同样原理的问题时还是不知道如何解决,以此又得浪费好长时间来解决,出来混总是要还的。

阅读更多
换一批

没有更多推荐了,返回首页