参数化查询 (Parameterized Query或Parameterized Statement)

https://translate.google.com.hk/translate?hl=zh-CN&sl=auto&tl=zh-CN&u=https%3A%2F%2Fzh.wikipedia.org%2Fwiki%2F%E5%8F%83%E6%95%B8%E5%8C%96%E6%9F%A5%E8%A9%A2&anno=2

参数化查询 (Parameterized Query或Parameterized Statement)是指在设计与资料库连结并存取资料时,在需要填入数值或资料的地方,使用参数 (Parameter)来给值,这个方法目前已被视为最有效可预防SQL注入攻击的攻击手法的防御方式。

除了安全因素,相比起拼接字符串的SQL语句,参数化的查询往往有性能优势。 因为参数化的查询能让不同的数据通过参数到达数据库,从而公用同一条SQL语句。 大多数数据库会缓存解释SQL语​​句产生的字节码而省下重复解析的开销。 如果采取拼接字符串的SQL语句,则会由于操作数据是SQL语句的一部分而非参数的一部分,而反复大量解释SQL语​​句产生不必要的开销。

PDO 

PDO用于PHP之内。 在使用PDO驱动时,参数查询的使用方法一般为:

  //实例化数据抽象层对象
 $db = new PDO ( 'pgsql:host=127.0.0.1;port=5432;dbname=testdb' );
 //对SQL语句执行prepare,得到PDOStatement对象
 $stmt = $db -> prepare ( 'SELECT * FROM "myTable" WHERE "id" = :id AND "is_valid" = :is_valid' );
 //绑定参数
 $stmt -> bindValue ( ':id' , $id );
 $stmt -> bindValue ( ':is_valid' , true );
 //查询
 $stmt -> execute ();
 //获取数据
 foreach ( $stmt as $row ) {
     var_dump ( $row );
 }

对于MySQL的特定驱动,也可以这样使用:

  $db = new mysqli ( "localhost" , "user" , "pass" , "database" );
 $stmt = $db -> prepare ( "SELECT priv FROM testUsers WHERE username=? AND password=?" );
 $stmt -> bind_param ( "ss" , $user , $pass );
 $stmt -> execute ();

值得注意的是,以下方式虽然能有效防止SQL注入 (归功于mysql_real_escape_string函数的转义),但并不是真正的参数化查询。 其本质仍然是拼接字符串的SQL语句。

  $query = sprintf ( "SELECT * FROM Users where UserName='%s' and Password='%s'" , 
                   mysql_real_escape_string ( $Username ), 
                   mysql_real_escape_string ( $Password ));
 mysql_query ( $query );

ODBC/JDBC 

ODBC使用C样式的函数/句柄接口,而JDBC用于Java之内。

  //C/C++, Microsoft Windows ODBC
 TCHAR szStatement [] = TEXT ( "select * from table where col1=?" );
 HSTMT hStmt ;
 SQLAllocHandle ( SQL_HANDLE_STMT , hDBC , & sRet . hStmt );
 SQLPrepare ( hStmt , szStatement , SQL_NTS );
 int iValue = 5 ;
 SQLLEN iLOI ;
 SQLBindParameter ( hStmt , 1 , SQL_PARAM_INPUT , SQL_C_LONG , SQL_INTEGER , sizeof ( iValue ), 0 , & iValue , sizeof ( iValue ), & iLOI );
 SQLExecute ( hStmt );
  //JDBC
 java . sql . PreparedStatement prep = connection . prepareStatement (
                 "SELECT * FROM users WHERE USERNAME = ? AND PASSWORD = ?" );
 prep . setString ( 1 , username );
 prep . setString ( 2 , password );
 prep . executeQuery ();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值