DBO 预处理语句和存储过程

来源:互联网 发布:汉文化 知乎 编辑:程序博客网 时间:2024/05/17 01:55

预处理语句可以带来两大好处:

  • 查询只需要被解析(或准备)一次,但也可以与相同的或不同的参数执行多次。准备查询时,数据库将分析,编译和优化查询的执行计划。对于复杂的查询,这个过程可能需要比较​​长的时间,这将显着放慢的应用程序,如果有需要用不同的参数多次重复相同的查询。通过使用准备好的语句的应用程序可避免重复分析/编译/优化周期。这意味着,预处理语句使用更少的资源,因而运行得更快。
  • 准备好的语句的参数不需要用引号括起来,驱动程序会自动处理这个问题。如果一个应用程序独占使用准备好的语句,开发人员可以确保没有SQL注入会发生(但是,如果其他部分正在兴建的查询与非转义的输入,SQL注入是可能的)。

 

 

#1使用准备好的语句重复插入这个例子执行INSERT查询,代以名称 的命名占位符。

<?php
$stmt
= $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name',$name);
$stmt->bindParam(':value',$value);

// insert one row
$name = 'one';
$value = 1;
$stmt->execute();

// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
?>

【举例】#2使用准备好的语句重复插入

这个例子执行INSERT查询取代的位置吗?占位符的名称 

<?php
$stmt 
$dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1$name);
$stmt->bindParam(2$value);

// insert one row
$name 'one';
$value 1;
$stmt->execute();

// insert another row with different values
$name 'two';
$value 2;
$stmt->execute();
?>

【举例】#3使用准备好的语句读取数据

这个例子的形式提供的关键值的基础上获取数据。用户输入的是自动进行加引号,所以不存在的SQL注入攻击的风险。

<?php
$stmt 
$dbh->prepare("SELECT * FROM REGISTRY where name = ?");
if (
$stmt->execute(array($_GET['name']))) {
  while (
$row $stmt->fetch()) {
    
print_r($row);
  }
}
?>

如果数据库驱动程序支持它,应用程序也可以绑定参数的输出和输入。输出参数通常用于检索存储过程中的值。稍微复杂一点,使用起来比输入参数,开发人员必须知道如何大时,他们可能把它绑定一个给定的参数输出参数。如果该值是大于他们建议的大小,则将引发一个错误。

例4调用存储过程的输出参数

<?php
$stmt 
$dbh->prepare("CALL sp_returns_string(?)");
$stmt->bindParam(1$return_valuePDO::PARAM_STR4000); 

// call the stored procedure
$stmt->execute();

print 
"procedure returned $return_value\n";
?>

开发人员还可以指定值的参数,输入和输出的语法类似于输出参数。在接下来的例子中,字符串'你好'被传递到存储过程中,当它返回时,返回值的程序hello被替换。

【举例】5#调用存储过程的输入/输出参数

<?php
$stmt 
$dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value 'hello';
$stmt->bindParam(1$valuePDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT4000); 

// call the stored procedure
$stmt->execute();

print 
"procedure returned $value\n";
?>

【举例】#6占位符的使用无效

<?php
$stmt 
$dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'");
$stmt->execute(array($_GET['name']));

// placeholder must be used in the place of the whole value
$stmt $dbh->prepare("SELECT * FROM REGISTRY where name LIKE ?");
$stmt->execute(array("%$_GET[name]%"));
?>

这个例子执行INSERT查询,代以名称 的命名占位符。