Mysql
 sql >> Base de données >  >> RDS >> Mysql

comment récupérer plusieurs jeux de résultats à partir d'une procédure stockée mysql dans laravel

J'utilise le code suivant et cela fonctionne parfaitement. Modifiez-le selon vos besoins.

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;
}

Exemple d'appel :

$params = ['2014-01-01','2014-12-31',100];
$results = APIDB::CallRaw('spGetData',$params);

L'appel résultant sera :

CALL spGetData(?,?,?)

S'il n'y a qu'un seul ensemble de résultats, il sera renvoyé tel quel. S'il y en a plus, il renverra un tableau d'ensembles de résultats. La clé utilise $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true); . Sans cela, un horrible SQLSTATE[HY000]: General error: 2053 une exception sera levée.

Le bloc try{} catch() est utilisé pour éliminer les jeux de résultats qui ne peuvent pas être récupérés. En particulier, j'ai des procédures qui renvoient deux jeux de résultats, l'un à la suite d'une mise à jour (ou d'autres instructions d'exécution) et le dernier en tant que données réelles. L'exception levée sur fetchAll() avec une requête d'exécution sera PDOException .

Attention :la fonction n'est pas optimisée. Vous pouvez le réécrire en un seul passage dans les paramètres.