跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
PHP存储过程
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= PHP存储过程 = '''PHP存储过程'''(Stored Procedures)是预编译的SQL语句集合,存储在数据库服务器中,可通过PHP调用执行。存储过程提高了代码复用性、安全性和性能,尤其适合处理复杂的数据库操作。 == 概述 == 存储过程是数据库对象,包含一组SQL语句和控制结构(如条件判断、循环等),具有以下特点: * '''预编译执行''':减少SQL解析开销 * '''减少网络流量''':只需传递过程名和参数 * '''增强安全性''':限制直接表访问 * '''事务管理''':可在过程中实现完整事务 == 基本语法 == === 创建存储过程 === MySQL语法示例: <syntaxhighlight lang="sql"> DELIMITER // CREATE PROCEDURE get_customer(IN cust_id INT) BEGIN SELECT * FROM customers WHERE id = cust_id; END // DELIMITER ; </syntaxhighlight> === PHP调用存储过程 === 基本调用方式: <syntaxhighlight lang="php"> <?php $pdo = new PDO("mysql:host=localhost;dbname=test", "user", "password"); $stmt = $pdo->prepare("CALL get_customer(?)"); $stmt->execute([42]); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); print_r($result); ?> </syntaxhighlight> == 参数类型 == 存储过程支持三种参数模式: <mermaid> pie title 参数类型分布 "IN (输入参数)" : 60 "OUT (输出参数)" : 25 "INOUT (双向参数)" : 15 </mermaid> === 示例:带输出参数的存储过程 === <syntaxhighlight lang="sql"> CREATE PROCEDURE count_products(OUT total INT) BEGIN SELECT COUNT(*) INTO total FROM products; END </syntaxhighlight> PHP调用方式: <syntaxhighlight lang="php"> $stmt = $pdo->prepare("CALL count_products(@total)"); $stmt->execute(); $stmt = $pdo->query("SELECT @total AS total"); echo $stmt->fetch()['total']; // 输出产品总数 </syntaxhighlight> == 事务处理 == 存储过程可封装完整事务: <syntaxhighlight lang="sql"> CREATE PROCEDURE transfer_funds( IN from_account INT, IN to_account INT, IN amount DECIMAL(10,2), OUT status VARCHAR(50) ) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SET status = 'Error occurred'; END; START TRANSACTION; UPDATE accounts SET balance = balance - amount WHERE id = from_account; UPDATE accounts SET balance = balance + amount WHERE id = to_account; COMMIT; SET status = 'Transfer successful'; END </syntaxhighlight> == 性能优化 == 存储过程相比动态SQL的优势: * 减少网络延迟 * 执行计划缓存 * 批量操作效率 性能对比公式: <math> T_{dynamic} = n \times (t_{parse} + t_{network} + t_{execute}) </math> <math> T_{stored} = t_{network} + n \times t_{execute} </math> == 实际案例 == === 电商平台订单处理 === <syntaxhighlight lang="sql"> CREATE PROCEDURE process_order( IN user_id INT, IN product_ids VARCHAR(255), IN quantities VARCHAR(255), OUT order_id INT ) BEGIN -- 变量声明 DECLARE i INT DEFAULT 0; DECLARE product_count INT; DECLARE current_pid INT; DECLARE current_qty INT; -- 创建订单 INSERT INTO orders (user_id, order_date) VALUES (user_id, NOW()); SET order_id = LAST_INSERT_ID(); -- 处理订单项 SET product_count = LENGTH(product_ids) - LENGTH(REPLACE(product_ids, ',', '')) + 1; WHILE i < product_count DO SET current_pid = SUBSTRING_INDEX(SUBSTRING_INDEX(product_ids, ',', i+1), ',', -1); SET current_qty = SUBSTRING_INDEX(SUBSTRING_INDEX(quantities, ',', i+1), ',', -1); INSERT INTO order_items (order_id, product_id, quantity) VALUES (order_id, current_pid, current_qty); UPDATE products SET stock = stock - current_qty WHERE id = current_pid; SET i = i + 1; END WHILE; -- 更新订单总价 UPDATE orders o SET total_amount = ( SELECT SUM(p.price * oi.quantity) FROM order_items oi JOIN products p ON oi.product_id = p.id WHERE oi.order_id = o.id ) WHERE o.id = order_id; END </syntaxhighlight> == 最佳实践 == 1. '''命名规范''':使用动词+名词格式(如`sp_UpdateInventory`) 2. '''错误处理''':始终包含错误处理逻辑 3. '''参数验证''':在过程中验证输入参数 4. '''文档注释''':为每个存储过程添加注释 5. '''性能测试''':监控存储过程执行时间 == 常见问题 == === 如何调试存储过程? === * 使用`SELECT`输出中间变量 * MySQL的`SHOW PROCEDURE STATUS` * 专门的数据库调试工具 === 存储过程与函数的区别? === {| class="wikitable" |- ! 特性 !! 存储过程 !! 函数 |- | 返回值 || 可无或多值 || 必须返回单值 |- | 调用方式 || CALL语句 || 表达式内调用 |- | 事务 || 支持 || 通常不支持 |- | 目的 || 执行操作 || 计算值 |} == 进阶主题 == * 动态SQL在存储过程中的应用 * 递归存储过程 * 存储过程的安全考虑(SQL注入防护) * 跨数据库兼容性问题 == 总结 == PHP存储过程是数据库编程的重要工具,通过将业务逻辑移至数据库层,可以提高应用程序的性能和安全性。初学者应从简单查询开始,逐步掌握参数传递、错误处理和事务管理等高级特性。 [[Category:编程语言]] [[Category:PHP]] [[Category:PHP数据库操作]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)