博客列表 >0817-数据库常用的CURD操作

0817-数据库常用的CURD操作

三九三伏
三九三伏原创
2022年09月02日 14:54:41409浏览

实例演示常用 的CURD操作,特别是各种常用组合,如fetch+while…

一、预处理参数绑定

PDO预处理
预处理的本质是sql语句的动态绑定
动态绑定就是执行时才绑定真实数据
SELECT * FROM `表名` WHERE `id` > ?
静态绑定,数据直接写到SQL语句中
SELECT * FROM `表名` WHERE `id` > 1

1. 动态绑定方式

1.1 匿名参数+索引数组

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //匿名参数:?
  5. $sql = 'INSERT `staff` SET `name` = ?, `gender` = ?, `email` = ?;';
  6. $stmt = $db->prepare($sql);
  7. //SQL语句中占位符“?”,用索引数组绑定真实数据
  8. $data = ['admin', 0, 'admin@php.cn'];
  9. $stmt->execute($data);
  10. echo '<hr>';
  11. //打印SQL预处理命令
  12. $stmt->debugDumpParams();
  13. echo '<br>'.$stmt->errorCode().'<br>';
  14. print_r($stmt->errorInfo());
  15. echo '<br>id = '.$db->lastInsertId().'<br>';

1.2 命名参数+关联数组

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //命名参数:“:xxxx”不用和前面一一对应
  5. $sql = 'INSERT `staff` SET `name` = :xname, `gender` = :pgender, `email` = :demail;';
  6. $stmt = $db->prepare($sql);
  7. //SQL语句中占位符“:xxxx”,用关联数组绑定真实数据
  8. // $data = [':xname' => 'admin', ':pgender' => 0, ':demail' => 'admin@php.cn'];
  9. //去掉冒号也是可以的
  10. $data = ['xname' => 'admin1', 'pgender' => 1, 'demail' => 'admin1@php.cn'];
  11. $stmt->execute($data);
  12. echo '<hr>';
  13. //打印SQL预处理命令
  14. $stmt->debugDumpParams();
  15. echo '<br>'.$stmt->errorCode().'<br>';
  16. print_r($stmt->errorInfo());
  17. echo '<br>id = '.$db->lastInsertId().'<br>';

“匿名参数+索引数组”和“命名参数+关联数组”用哪个好?
用哪个都可以,看个人喜好。

1.3 参数绑定:值绑定 bindValue()

  1. /**
  2. * 为什么要单独设置参数,而不是在execute()时传参?
  3. * execute()默认参数都是字符类型
  4. * 通常数字型字符写入数据表时,会转换成正确类型,不会有问题。
  5. * 但在分页操作时,会导致错误。
  6. * 在参数绑定时,强制类型限制,就很有必要。
  7. */
  8. namespace pdo_edu;
  9. use PDO;
  10. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  11. //匿名参数:?
  12. $sql = 'INSERT `staff` SET `name` = ?, `gender` = ?, `email` = ?;';
  13. $stmt = $db->prepare($sql);
  14. //bindValue()值绑定,静态绑定,所有参数有确定值。
  15. // bindValue(key, value, type),匿名占位符,索引从1开始。
  16. // $stmt->bindValue(1, 'admin3', PDO::PARAM_STR);
  17. // $stmt->bindValue(2, 0, PDO::PARAM_INT);
  18. // $stmt->bindValue(3, 'admin3@php.cn', PDO::PARAM_STR);
  19. // 上面是写死的,更灵活应该用数组传参。
  20. list($name, $gender, $email) = ['admin4', 1, 'admin4@php.cn'];
  21. $stmt->bindValue(1, $name, PDO::PARAM_STR);
  22. $stmt->bindValue(2, $gender, PDO::PARAM_INT);
  23. $stmt->bindValue(3, $email, PDO::PARAM_STR);
  24. list($name, $gender, $email) = ['admin5', 0, 'admin5@php.cn'];
  25. $stmt->bindValue(1, $name, PDO::PARAM_STR);
  26. $stmt->bindValue(2, $gender, PDO::PARAM_INT);
  27. $stmt->bindValue(3, $email, PDO::PARAM_STR);
  28. $stmt->execute();
  29. echo '<hr>';
  30. //打印SQL预处理命令
  31. $stmt->debugDumpParams();
  32. echo '<br>'.$stmt->errorCode().'<br>';
  33. print_r($stmt->errorInfo());
  34. echo '<br>id = '.$db->lastInsertId().'<br>';

每插入一条就得绑定一次,也不方便灵活。

1.4 参数绑定:引用绑定bindParam()

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //heredoc
  5. $sql = <<<SQL
  6. INSERT `staff`
  7. SET `name` = ?, `gender` = ?, `email` = ?;
  8. SQL;
  9. $stmt = $db->prepare($sql);
  10. // 引用绑定
  11. $stmt->bindParam(1, $name, PDO::PARAM_STR);
  12. $stmt->bindParam(2, $gender, PDO::PARAM_INT);
  13. $stmt->bindParam(3, $email, PDO::PARAM_STR);
  14. // list($name, $gender, $email) = ['admin6', 1, 'admin6@php.cn'];
  15. // $stmt->execute();
  16. // echo '<hr>';
  17. // 在增加两条条
  18. // list($name, $gender, $email) = ['admin7', 0, 'admin7@php.cn'];
  19. // $stmt->execute();
  20. // echo '<hr>';
  21. // list($name, $gender, $email) = ['admin8', 1, 'admin8@php.cn'];
  22. // $stmt->execute();
  23. // echo '<hr>';
  24. // $stmt->execute();
  25. // echo '<hr>';
  26. // //打印SQL预处理命令
  27. // $stmt->debugDumpParams();
  28. // echo '<br>'.$stmt->errorCode().'<br>';
  29. // print_r($stmt->errorInfo());
  30. // echo '<br>id = '.$db->lastInsertId().'<br>';
  31. // 用循环和二维数组添加多条
  32. $data = [
  33. ['admin9', 0, 'admin9@php.cn'],
  34. ['admin10', 1, 'admin10@php.cn'],
  35. ['admin11', 0, 'admin11@php.cn'],
  36. ];
  37. foreach($data as list($name, $gender, $email)){
  38. $stmt->execute();
  39. echo '<hr>';
  40. //打印SQL预处理命令
  41. $stmt->debugDumpParams();
  42. echo '<br>'.$stmt->errorCode().'<br>';
  43. print_r($stmt->errorInfo());
  44. echo '<br>id = '.$db->lastInsertId().'<br>';
  45. }

1.5 错误处理

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //heredoc
  5. $sql = <<<SQL
  6. INSERT `staff` SET `name` = ?, `gender` = ?, `email` = ?;
  7. SQL;
  8. $stmt = $db->prepare($sql);
  9. //注释“引用绑定”,引起错误
  10. // $stmt->bindParam(1, $name, PDO::PARAM_STR);
  11. // $stmt->bindParam(2, $gender, PDO::PARAM_INT);
  12. // $stmt->bindParam(3, $email, PDO::PARAM_STR);
  13. $data = [
  14. ['admin12', 0, 'admin12@php.cn'],
  15. //['admin13', 0, 'admin13@php.cn'],
  16. ];
  17. foreach($data as list($name, $gender, $email)){
  18. if($stmt->execute()){
  19. if($stmt->rowCount() > 0){
  20. echo 'sql执行成功,id ='.$db->lastInsertId().'<br>';
  21. echo '<hr>';
  22. }else{
  23. echo '执行失败';
  24. print_r($stmt->errorInfo());
  25. }
  26. }else{
  27. echo 'sql执行失败';
  28. print_r($stmt->errorInfo());
  29. }
  30. }

Tips

  1. else:应用于开发调试阶段,生产环境中应将错误信息集中写到日志文件中。
  2. sql执行失败很常见,通常是语法错误,例如字段名写错等。
  3. 新增失败通常是权限问题,如没有插入权限或者当前表被锁定只读等,磁盘满也有可能。

1.6 更新

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //heredoc
  5. $sql = <<<SQL
  6. UPDATE `staff` SET `name` = ?, `gender` = ?, `email` = ?
  7. WHERE `id`= ?;
  8. SQL;
  9. // !!!!最高提示:禁止无条件更新,生产环境必须杜绝。
  10. // stripos()忽略大小写
  11. if (false === stripos($sql, 'where'))
  12. {
  13. exit('禁止无条件更新!');
  14. }
  15. $stmt = $db->prepare($sql);
  16. $stmt->bindParam(1, $name, PDO::PARAM_STR);
  17. $stmt->bindParam(2, $gender, PDO::PARAM_INT);
  18. $stmt->bindParam(3, $email, PDO::PARAM_STR);
  19. $stmt->bindParam(4, $id, PDO::PARAM_INT);
  20. $data = [
  21. ['admin8', 0, 'admin8@php.cn', 8],
  22. ];
  23. foreach($data as list($name, $gender, $email, $id)){
  24. if($stmt->execute()){
  25. if($stmt->rowCount() > 0){
  26. echo '成功更新了'.$stmt->rowCount().'条记录<br>';
  27. echo '<hr>';
  28. }else{
  29. echo '更新重复:没有记录被更新!<br>';
  30. print_r($stmt->errorInfo());
  31. $stmt->debugDumpParams();
  32. }
  33. }else{
  34. echo 'sql执行失败';
  35. print_r($stmt->errorInfo());
  36. }
  37. }

成功时,

重复的更新将被拦截,

  1. ....
  2. //不写条件WHERE测试
  3. $sql = <<<SQL
  4. UPDATE `staff` SET `name` = ?, `gender` = ?, `email` = ?
  5. ;
  6. SQL;
  7. // 最高提示:禁止无条件更新,生产环境必须杜绝。
  8. // stripos()忽略大小写
  9. if (false === stripos($sql, 'where'))
  10. {
  11. exit('禁止无条件更新!');
  12. }
  13. ....

1.7 删除

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //heredoc
  5. $sql = <<<SQL
  6. DELETE FROM `staff`
  7. WHERE `id`= ?;
  8. SQL;
  9. // 最高提示:禁止无条件删除,生产环境必须杜绝。
  10. // stripos()忽略大小写
  11. if (false === stripos($sql, 'where'))
  12. {
  13. exit('禁止无条件删除!');
  14. }
  15. $stmt = $db->prepare($sql);
  16. $stmt->bindParam(1, $id, PDO::PARAM_INT);
  17. $data = [
  18. [11],
  19. [10],
  20. ];
  21. foreach($data as list($id)){
  22. echo $id.'<br>';
  23. if($stmt->execute()){
  24. if($stmt->rowCount() > 0){
  25. echo '成功删除了'.$stmt->rowCount().'条记录<br>';
  26. echo '<hr>';
  27. }else{
  28. echo '重复删除:没有记录被删除!<br>';
  29. print_r($stmt->errorInfo());
  30. // $stmt->debugDumpParams();
  31. }
  32. }else{
  33. echo 'sql执行失败';
  34. print_r($stmt->errorInfo());
  35. }
  36. }

1.8 查询

1.8.1 fetch + while

  1. // 查询 fetch + while
  2. namespace pdo_edu;
  3. use PDO;
  4. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  5. //heredoc
  6. $sql = <<<SQL
  7. SELECT `id`, `name`, `email` FROM `staff`
  8. LIMIT ?;
  9. SQL;
  10. $stmt = $db->prepare($sql);
  11. // $num = 5;
  12. // $stmt->bindParam(1, $num, PDO::PARAM_INT);
  13. $stmt->bindValue(1, 5, PDO::PARAM_INT);
  14. if($stmt->execute()){
  15. // fetch()逐条获取,指针自动后移指向下一条,失败返回false,成功返回记录。
  16. // $staff = $stmt->fetch(PDO::FETCH_ASSOC);
  17. // if($staff)
  18. // {
  19. // printf('<pre>%s</pre><br>',print_r($staff, true));
  20. // }else
  21. // {
  22. // echo '没有查询到数据!<br>';
  23. // }
  24. while($staff = $stmt->fetch(PDO::FETCH_ASSOC))
  25. {
  26. printf('<pre>%s</pre><br>',print_r($staff, true));
  27. }
  28. }else{
  29. echo 'sql执行失败';
  30. print_r($stmt->errorInfo());
  31. $stmt->debugDumpParams();
  32. }

1.8.2 fetchall

  1. // 查询 fetchall
  2. namespace pdo_edu;
  3. use PDO;
  4. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  5. //heredoc
  6. $sql = <<<SQL
  7. SELECT `id`, `name`, `email` FROM `staff`
  8. LIMIT ?;
  9. SQL;
  10. $stmt = $db->prepare($sql);
  11. // $num = 5;
  12. // $stmt->bindParam(1, $num, PDO::PARAM_INT);
  13. $stmt->bindValue(1, 4, PDO::PARAM_INT);
  14. if($stmt->execute()){
  15. // fetchall()获取全部记录。
  16. while($staffs = $stmt->fetchAll(PDO::FETCH_ASSOC))
  17. {
  18. foreach($staffs as
  19. $staff){
  20. printf('<pre>%s</pre><br>',print_r($staff, true));
  21. }
  22. }
  23. }else{
  24. echo 'sql执行失败';
  25. print_r($stmt->errorInfo());
  26. $stmt->debugDumpParams();
  27. }

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议