Frage

Ich habe eine gespeicherte Prozedur, die mehrere Ergebnismengen hat. Wie komme ich zum zweiten Ergebnismenge in mysqli vorrücken, um diese Ergebnisse zu erhalten?

Lassen Sie uns sagen, es ist eine gespeicherte Prozedur wie:

create procedure multiples( param1 INT, param2 INT )
BEGIN

SELECT * FROM table1 WHERE id = param1;

SELECT * FROM table2 WHERE id = param2;

END $$

Die PHP ist so etwas wie folgt aus:

$stmt = mysqli_prepare($db, 'CALL multiples(?, ?)');

mysqli_stmt_bind_param( $stmt, 'ii', $param1, $param2 );

mysqli_stmt_execute( $stmt );

mysqli_stmt_bind_result( $stmt, $id );

Dann ist dies der Teil kann ich nicht an der Arbeit. Ich habe versucht, mysqli_next_result mit auf die nächste Ergebnismenge zu bewegen, aber nicht bekommen kann, damit es funktioniert. Wir haben es mit mysqli_store_result und mysqli_fetch_assoc / array / Zeile, aber aus irgendeinem Grunde all ints erhalten zurückgegeben als leere Strings zu arbeiten.

Jeder sonst über diese kommen und eine Lösung?

War es hilfreich?

Lösung

Ich glaube, Sie etwas hier sind vermisst (Folgendes wurde nicht geprüft):

$stmt = mysqli_prepare($db, 'CALL multiples(?, ?)');
mysqli_stmt_bind_param($stmt, 'ii', $param1, $param2);
mysqli_stmt_execute($stmt);
// fetch the first result set
$result1 = mysqli_use_result($db);
// you have to read the result set here 
while ($row = $result1->fetch_assoc()) {
    printf("%d\n", $row['id']);
}
// now we're at the end of our first result set.
mysqli_free_result($result1);

//move to next result set
mysqli_next_result($db);
$result2 = mysqli_use_result($db);
// you have to read the result set here 
while ($row = $result2->fetch_assoc()) {
    printf("%d\n", $row['id']);
}
// now we're at the end of our second result set.
mysqli_free_result($result2);

// close statement
mysqli_stmt_close($stmt);

Mit PDO Ihr Code würde wie folgt aussehen:

$stmt = $db->prepare('CALL multiples(:param1, :param2)');
$stmt->execute(array(':param1' => $param1, ':param2' => $param2));
// read first result set
while ($row = $stmt->fetch()) {
    printf("%d\n", $row['id']);
}
$stmt->nextRowset();
// read second result set
while ($row = $stmt->fetch()) {
    printf("%d\n", $row['id']);
}

Aber ich habe gehört, dass der PDOStatement::nextRowset() nicht mit der Umsetzung MySQL PDO Treiber es unmöglich macht, mehrere Ergebnisse zu erhalten:

Also, je nach PHP-Version, dann würden Sie mit Ihrem halten müssen mysqli -Lösung. Durch die Art und Weise: Verwenden Sie den prozeduralen Stil bewusst? Mit objektorientiertem Stil mit mysqli würde Ihren Code aussieht eine wenig ansprechende (meine persönliche Meinung) machen.

Andere Tipps

Das hat wirklich gut für mich gearbeitet hat, wird es mit (als Beispiel), so viele Select-Listen umgehen, wie es in Ihrem SP ist. Beachten Sie, wie Sie den $ Anruf zu schließen, bevor Sie dann zu den OUT-Parametern von Ihrem SP bekommen ...

?><pre><?
$call = mysqli_prepare($db, 'CALL test_lists(?, ?, @result)');
if($call == false) {
    echo "mysqli_prepare (\$db, 'CALL test_lists(?, ?, @result) FAILED!!!\n";
} else {
    // A couple of example IN parameters for your SP...
    $s_1 = 4;
    $s_2 = "Hello world!";

    // Here we go (safer way of avoiding SQL Injections)...
    mysqli_stmt_bind_param($call, 'is', $s_1, $s_2);

    // Make the call...
    if(mysqli_stmt_execute($call) == false) {
        echo "mysqli_stmt_execute(\$call) FAILED!!!\n";
    } else {
        //print_r($call);

        // Loop until we run out of Recordsets...
        $set = 0;
        while ($recordset = mysqli_stmt_get_result($call)) {
            ++$set;
            //print_r($recordset);
            echo "\nRecordset #" . $set . "...\n";
            if ($recordset->num_rows > 0) {
                $ctr = 0;
                while ($row = $recordset->fetch_assoc()) {
                    ++$ctr;
                    //print_r($row);
                    echo "\t" . $ctr . ": ";
                    forEach($row as $key => $val) {
                        echo "[" . $key . "] " . $val . "\t";
                    }
                    echo "\n";
                }
            }
            echo $recordset->num_rows . " record" . ($recordset->num_rows == 1 ? "" : "s") . ".\n";
            // Clean up, ready for next iteration...
            mysqli_free_result($recordset);

            // See if we can get another Recordset...
            mysqli_stmt_next_result($call);
        }

        // Then you have to close the $call...
        mysqli_stmt_close($call);
        // ...in order to get to the SP's OUT parameters...
        $select = mysqli_query($db, "SELECT @result");
        $row = mysqli_fetch_row($select);
        $result = $row[0];
        echo "\nOUT @result = " . $result . "\n";
    }
}
?></pre><?

Und das ist, was die Ausgabe des obigen Code sieht meinen test_lists wie mit SP ...

Recordset #1...
    1: [s_1] 4  [user_name] Andrew Foster   
    2: [s_1] 4  [user_name] Cecil   
    3: [s_1] 4  [user_name] Sheff   
3 records.

Recordset #2...
    1: [s_2] Hello world!   [section_description] The Law   
    2: [s_2] Hello world!   [section_description] History   
    3: [s_2] Hello world!   [section_description] Wisdom Literature 
    4: [s_2] Hello world!   [section_description] The Prophets  
    5: [s_2] Hello world!   [section_description] The Life of Jesus and the Early Church    
    6: [s_2] Hello world!   [section_description] Letters from the Apostle Paul 
    7: [s_2] Hello world!   [section_description] Other Letters from Apostles and Prophets  
    8: [s_2] Hello world!   [section_description] Prophecy - warnings for the present and revelation of the future  
8 records.

OUT @result = 16

Es sieht aus wie MySQLi nur mehrere Ergebnismengen durch mysqli_multi_query() unterstützen können, da MySQLi_STMT Objekte anders MySQLi_Result Objekten arbeiten.

PDO scheint etwas abstrahiert zu sein, mit dem PDOStatement Objekte in der Lage, mehrere Ergebnisse für beide regelmäßige Abfragen (PDO::query) und Prepared Statements (PDO:prepare).

Griff
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top