Ich verwende den folgenden Code und es funktioniert einwandfrei. Passen Sie es an Ihre Bedürfnisse an.
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;
}
Beispielaufruf:
$params = ['2014-01-01','2014-12-31',100];
$results = APIDB::CallRaw('spGetData',$params);
Der resultierende Aufruf lautet:
CALL spGetData(?,?,?)
Wenn es nur eine Ergebnismenge gibt, wird sie unverändert zurückgegeben. Wenn mehr vorhanden sind, wird ein Array von Ergebnismengen zurückgegeben. Der Schlüssel verwendet $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
. Ohne sie ein schrecklicher SQLSTATE[HY000]: General error: 2053
Ausnahme wird geworfen.
Der Block try{} catch() wird verwendet, um die Ergebnismengen zu eliminieren, die nicht abgerufen werden können. Insbesondere habe ich Prozeduren, die zwei Ergebnismengen zurückgeben, eine als Ergebnis einer Aktualisierung (oder anderer Ausführungsanweisungen) und die letzte als die echten Daten. Die Ausnahme, die bei fetchAll()
ausgelöst wird bei einer Ausführungsabfrage wird PDOException
sein .
Achtung:Die Funktion ist nicht optimiert. Sie können es mit einem einzigen Durchgang durch die Parameter umschreiben.