存储过程(Stored Procedure)是预先编译并存储在数据库中的SQL语句集合,可以通过一个简单的调用来执行复杂的数据库操作。在Symfony和Doctrine中使用存储过程可以带来性能优势,特别是对于复杂的批量操作。
// 在Repository中
public function callUpdateStatusProcedure(int $userId, string $status): void
{
$conn = $this->getEntityManager()->getConnection();
$sql = 'CALL update_user_status(:userId, :status)';
$stmt = $conn->prepare($sql);
$stmt->execute(['userId' => $userId, 'status' => $status]);
}
public function getUserStats(int $userId): array
{
$conn = $this->getEntityManager()->getConnection();
$sql = 'CALL get_user_stats(:userId)';
$stmt = $conn->prepare($sql);
$stmt->execute(['userId' => $userId]);
return $stmt->fetchAllAssociative();
}
public function callComplexProcedure(int $param1, string $param2): array
{
$em = $this->getEntityManager();
$rsm = new ResultSetMapping();
// 映射结果集到实体(如果需要)
$rsm->addEntityResult('App\Entity\User', 'u');
$rsm->addFieldResult('u', 'id', 'id');
// 添加其他字段映射...
$query = $em->createNativeQuery('CALL complex_procedure(?, ?)', $rsm);
$query->setParameter(1, $param1);
$query->setParameter(2, $param2);
return $query->getResult();
}
原因:可能是没有正确获取多个结果集或存储过程没有返回预期数据
解决方案:
// 对于可能返回多个结果集的存储过程
$conn->beginTransaction();
try {
$stmt = $conn->prepare('CALL multi_result_procedure(?)');
$stmt->execute(['param' => $value]);
$results = [];
do {
$results[] = $stmt->fetchAllAssociative();
} while ($stmt->nextRowset());
$conn->commit();
return $results;
} catch (\Exception $e) {
$conn->rollBack();
throw $e;
}
原因:参数类型不匹配或参数顺序错误
解决方案:
// 使用命名参数而非位置参数
$stmt = $conn->prepare('CALL procedure_name(:param1, :param2)');
$stmt->execute([
'param1' => $value1,
'param2' => $value2
]);
原因:存储过程内部有事务而外部也有事务
解决方案:
// 明确管理事务
$conn->beginTransaction();
try {
$conn->executeStatement('CALL transactional_procedure(?)', [$param]);
$conn->commit();
} catch (\Exception $e) {
$conn->rollBack();
throw $e;
}
DELIMITER //
CREATE PROCEDURE update_user_credits(IN user_id INT, IN credit_change INT, OUT new_credit INT)
BEGIN
UPDATE users SET credits = credits + credit_change WHERE id = user_id;
SELECT credits INTO new_credit FROM users WHERE id = user_id;
END //
DELIMITER ;
// UserRepository.php
public function updateUserCredits(int $userId, int $creditChange): int
{
$conn = $this->getEntityManager()->getConnection();
$sql = 'CALL update_user_credits(:userId, :creditChange, @newCredit)';
$conn->executeStatement($sql, [
'userId' => $userId,
'creditChange' => $creditChange
]);
// 获取输出参数
$stmt = $conn->executeQuery('SELECT @newCredit as newCredit');
$result = $stmt->fetchAssociative();
return (int)$result['newCredit'];
}
通过这种方式,您可以高效地在Symfony和Doctrine应用中利用存储过程的优势。
没有搜到相关的文章