Tôi đang sử dụng đoạn mã sau và nó hoạt động hoàn hảo. Thay đổi nó cho phù hợp với nhu cầu của bạn.
public static function CallRaw($procName, $parameters = null, $isExecute = false)
{
$syntax = '';
for ($i = 0; $i < count($parameters); $i++) {
$syntax .= (!empty($syntax) ? ',' : '') . '?';
}
$syntax = 'CALL ' . $procName . '(' . $syntax . ');';
$pdo = DB::connection()->getPdo();
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
$stmt = $pdo->prepare($syntax,[\PDO::ATTR_CURSOR=>\PDO::CURSOR_SCROLL]);
for ($i = 0; $i < count($parameters); $i++) {
$stmt->bindValue((1 + $i), $parameters[$i]);
}
$exec = $stmt->execute();
if (!$exec) return $pdo->errorInfo();
if ($isExecute) return $exec;
$results = [];
do {
try {
$results[] = $stmt->fetchAll(\PDO::FETCH_OBJ);
} catch (\Exception $ex) {
}
} while ($stmt->nextRowset());
if (1 === count($results)) return $results[0];
return $results;
}
Cuộc gọi ví dụ:
$params = ['2014-01-01','2014-12-31',100];
$results = APIDB::CallRaw('spGetData',$params);
Cuộc gọi kết quả sẽ là:
CALL spGetData(?,?,?)
Nếu chỉ có một tập kết quả, nó sẽ được trả về nguyên trạng. Nếu có nhiều hơn, nó sẽ trả về một mảng tập hợp kết quả. Khóa đang sử dụng $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
. Nếu không có nó, một SQLSTATE[HY000]: General error: 2053
ngoại lệ sẽ được ném ra.
Khối try {} catch () được sử dụng để loại bỏ các tập kết quả không thể tìm nạp được. Đặc biệt, tôi có các thủ tục trả về hai tập kết quả, một là kết quả của một bản cập nhật (hoặc các câu lệnh thực thi khác) và một là dữ liệu thực. Ngoại lệ được đưa ra trên fetchAll()
với một truy vấn thực thi sẽ là PDOException
.
Cảnh báo:chức năng không được tối ưu hóa. Bạn có thể viết lại nó bằng một lần chuyển qua các tham số.