本文目录导读:

在ThinkPHP中调用存储过程,主要有以下几种方式:
使用原生SQL查询
使用query()方法(返回结果集)
// 调用返回结果集的存储过程
$result = Db::query("CALL get_user_list(?)", [$userId]);
// 带多个参数
$result = Db::query("CALL get_user_info(?, ?)", [$userId, $status]);
使用execute()方法(不返回结果集)
// 执行不返回结果的存储过程
Db::execute("CALL update_user_status(?)", [$userId]);
// 带多个参数
Db::execute("CALL batch_update_users(?, ?)", [$startId, $endId]);
使用模型调用
// 在模型中定义方法
class User extends Model
{
// 调用存储过程
public static function callGetUserList($params)
{
return Db::query("CALL get_user_list(?)", $params);
}
// 调用存储过程并返回结果
public static function callProcedure($procName, $params = [])
{
$placeholders = implode(',', array_fill(0, count($params), '?'));
$sql = "CALL {$procName}({$placeholders})";
return Db::query($sql, $params);
}
}
// 调用方式
$userList = User::callGetUserList([$userId]);
使用参数绑定(更安全的写法)
// 使用命名绑定
$result = Db::query("CALL get_user_by_condition(:id, :status)", [
':id' => $userId,
':status' => 1
]);
// 或者使用PDO绑定
$pdo = Db::getPdo();
$stmt = $pdo->prepare("CALL get_user_list(?, ?)");
$stmt->bindValue(1, $userId, PDO::PARAM_INT);
$stmt->bindValue(2, $status, PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetchAll();
处理存储过程的OUT参数
// 使用PDO处理OUT参数
$pdo = Db::getPdo();
$stmt = $pdo->prepare("CALL get_user_count(?)");
$stmt->bindParam(1, $count, PDO::PARAM_INT, 11);
$stmt->execute();
echo "用户总数: " . $count;
// 多个OUT参数
$stmt = $pdo->prepare("CALL get_stats(?, ?)");
$stmt->bindParam(1, $totalUsers, PDO::PARAM_INT, 11);
$stmt->bindParam(2, $activeUsers, PDO::PARAM_INT, 11);
$stmt->execute();
echo "总用户: $totalUsers, 活跃用户: $activeUsers";
封装成通用方法
// 封装一个通用的存储过程调用方法
class ProcedureService
{
/**
* 调用存储过程
* @param string $procedure 存储过程名称
* @param array $params 参数数组
* @param bool $returnResult 是否返回结果集
* @return mixed
*/
public static function call($procedure, $params = [], $returnResult = true)
{
// 构建参数占位符
$placeholders = array_fill(0, count($params), '?');
$sql = "CALL {$procedure}(".implode(',', $placeholders).")";
if ($returnResult) {
return Db::query($sql, $params);
} else {
return Db::execute($sql, $params);
}
}
// 调用示例
public function example()
{
// 返回结果集
$list = ProcedureService::call('get_user_list', [1, 100]);
// 不返回结果
ProcedureService::call('update_user', [1, '张三'], false);
}
}
处理多个结果集
// 当存储过程返回多个结果集时
$pdo = Db::getPdo();
$stmt = $pdo->prepare("CALL get_multi_results(?)");
$stmt->execute([$userId]);
// 获取第一个结果集
$firstResult = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 移动到下一个结果集
$stmt->nextRowset();
$secondResult = $stmt->fetchAll(PDO::FETCH_ASSOC);
事务中的存储过程调用
// 在事务中调用存储过程
Db::startTrans();
try {
// 执行存储过程
Db::execute("CALL update_user_balance(?, ?)", [$userId, -100]);
Db::execute("CALL record_transaction(?, ?, ?)", [$userId, -100, '消费']);
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
throw $e;
}
参数类型指定
// 强制指定参数类型
$pdo = Db::getPdo();
$stmt = $pdo->prepare("CALL search_users(?, ?)");
// 绑定参数并指定类型
$stmt->bindValue(1, $keyword, PDO::PARAM_STR);
$stmt->bindValue(2, $pageSize, PDO::PARAM_INT);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
注意事项
- 安全性:始终使用参数绑定,避免SQL注入
- 参数匹配:确保传递给存储过程的参数数量和类型正确
- 连接状态:存储过程执行后可能占用连接,记得处理结果集
- 错误处理:使用try-catch捕获异常,提供友好的错误提示
通过这些方法,你可以在ThinkPHP项目中灵活地调用各种存储过程。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播