Jag använder följande kod och den fungerar felfritt. Ändra det så att det passar dina behov.
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;
}
Exempelsamtal:
$params = ['2014-01-01','2014-12-31',100];
$results = APIDB::CallRaw('spGetData',$params);
Det resulterande anropet blir:
CALL spGetData(?,?,?)
Om det bara finns en resultatuppsättning kommer den att returneras som den är. Om det finns fler kommer det att returnera en rad resultatuppsättningar. Nyckeln använder $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
. Utan det, en hemsk SQLSTATE[HY000]: General error: 2053
undantag kommer att kastas.
Blocket try{} catch() används för att eliminera resultatuppsättningar som inte kan hämtas. Speciellt har jag procedurer som returnerar två resultatuppsättningar, en som ett resultat av en uppdatering (eller andra exekveringssatser) och den sista som verklig data. Undantaget kastas på fetchAll()
med en exekveringsfråga blir PDOException
.
Varning:funktionen är inte optimerad. Du kan skriva om det med en enda passage genom parametrarna.