Saya menggunakan kode berikut dan berfungsi dengan sempurna. Ubah sesuai kebutuhan Anda.
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;
}
Contoh panggilan:
$params = ['2014-01-01','2014-12-31',100];
$results = APIDB::CallRaw('spGetData',$params);
Panggilan yang dihasilkan adalah:
CALL spGetData(?,?,?)
Jika hanya ada satu hasil, itu akan dikembalikan apa adanya. Jika ada lebih banyak, itu akan mengembalikan array set hasil. Kuncinya menggunakan $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
. Tanpa itu, SQLSTATE[HY000]: General error: 2053
pengecualian akan dilempar.
Blok try{} catch() digunakan untuk menghilangkan hasil yang tidak bisa diambil. Khususnya, saya memiliki prosedur yang mengembalikan dua kumpulan hasil, satu sebagai hasil dari pembaruan (atau pernyataan eksekusi lainnya) dan yang terakhir sebagai data nyata. Pengecualian dilemparkan pada fetchAll()
dengan kueri eksekusi akan menjadi PDOException
.
Peringatan:fungsi ini tidak dioptimalkan. Anda dapat menulis ulang dengan satu kali melewati parameter.