2009-11-05 11 views
13

में संग्रहित प्रक्रिया के साथ एकाधिक परिणाम सेट पुनर्प्राप्त करना मेरे पास एक संग्रहीत प्रक्रिया है जिसमें एकाधिक परिणाम सेट हैं। मैं उन परिणामों को प्राप्त करने के लिए mysqli में दूसरे परिणाम सेट पर कैसे आगे बढ़ूं?PHP/mysqli

create procedure multiples(param1 INT, param2 INT) 
BEGIN 

SELECT * FROM table1 WHERE id = param1; 

SELECT * FROM table2 WHERE id = param2; 

END $$ 

पीएचपी कुछ इस तरह है:

मान लें कि यह की तरह एक संग्रहीत proc है चलो

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

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

mysqli_stmt_execute($stmt); 

mysqli_stmt_bind_result($stmt, $id); 

तो इस भाग मैं काम करने के लिए नहीं मिल सकता है। मैंने अगले परिणाम सेट पर जाने के लिए mysqli_next_result का उपयोग करने का प्रयास किया है, लेकिन इसे काम पर नहीं लाया जा सकता है। हमने इसे mysqli_store_result और mysqli_fetch_assoc/array/पंक्ति के साथ काम करने के लिए प्राप्त किया, लेकिन किसी कारण से सभी स्याही खाली तारों के रूप में लौट आती हैं।

कोई और इस पर आ गया है और समाधान है?

+0

क्या प्रक्रिया कॉल एक तैयार कथन के बजाय mysqli_multi_query() का उपयोग करके ठीक से वापस आती है? – gapple

+0

ओह, क्षमा करें। मेरी पहली प्रतिक्रिया आपकी टिप्पणी सही ढंग से नहीं पढ़ रही थी। हमें तैयार वक्तव्यों का उपयोग करने की आवश्यकता है, लेकिन क्वेरी सही है और पहले परिणाम सेट के लिए काम करता है। मैं सिर्फ यह नहीं समझ सकता कि इसे दूसरे परिणाम सेट में कैसे अग्रिम किया जाए। – MacAnthony

उत्तर

13

मुझे लगता है कि तुम यहाँ कुछ भूल रहे हैं (निम्नलिखित परीक्षण किया नहीं किया गया है):

$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); 

PDO अपने कोड का उपयोग दिखाई देगा:

$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']); 
} 

लेकिन मैंने सुना है कि PDOStatement::nextRowset()MySQL PDO driver के साथ लागू नहीं किया गया है जिससे कई परिणाम सेट पुनर्प्राप्त करना असंभव हो जाता है:

तो, अपने PHP संस्करण के आधार पर, आप अपने mysqli -solution साथ रहना होगा। वैसे: क्या आप जानबूझकर प्रक्रियात्मक शैली का उपयोग करते हैं? mysqli के साथ ऑब्जेक्ट उन्मुख शैली का उपयोग करने से आपका कोड थोड़ा अधिक आकर्षक (मेरी व्यक्तिगत राय) दिखाई देगा।

+0

के साथ उपलब्ध हैं पीडीओ और अभी भी यह देखने के लिए मूल्यांकन करना होगा कि यह माइस्क्ली से बेहतर है या नहीं, लेकिन यह एक मौजूदा परियोजना है और डीबी परत को बदलना यथार्थवादी नहीं है। 2 डीबी परतों को मिलाकर खराब डिजाइन, आईएमओ है। – MacAnthony

+0

हां, आप सही हैं, मैंने mysqli_stmt_fetch ($ stmt) लाइन छोड़ी है। पिछले डेवलपर ने परिणाम सेट ऑब्जेक्ट्स के बजाय mysqli-stmt ऑब्जेक्ट्स का उपयोग किया था। जैसा कि कहा गया है, जब हमने fetch_assoc के साथ परिणाम सेट करने का प्रयास किया, तो सभी int कॉलम रिक्त तार के रूप में लौट आए। – MacAnthony

+0

यह एक पुराना प्रश्न और उत्तर है, लेकिन mysqli समाधान अब काम नहीं करता है ... 'mysqli_use_result'' mysqli_stmt_execute' के बाद 'झूठी' वापस आ जाएगा ... 'mysqli_use_result' का उपयोग केवल "क्वेरी" के बाद किया जा सकता है –

1

ऐसा लगता है कि MySQLi केवल mysqli_multi_query() के माध्यम से एकाधिक परिणाम सेट का समर्थन कर सकता है, क्योंकि MySQLi_STMT ऑब्जेक्ट्स MySQLi_Result ऑब्जेक्ट्स से अलग-अलग काम करते हैं।

पीडीओ, कुछ और अधिक पृथक हो रहा है PDOStatement वस्तुओं दोनों नियमित प्रश्नों (PDO::query) और तैयार बयान (PDO:prepare) के लिए एकाधिक परिणाम सेट को संभालने में सक्षम होने के साथ।

+0

'$ stmt-> get_results()' ... $ $ stmt-> next_result() 'का उपयोग करके कई परिणाम सेट पर भी पुन: सक्रिय हो सकता है .. दोनों फ़ंक्शन/विधियां केवल" MySQL मूल चालक " –

0

इसने मेरे लिए वास्तव में अच्छा काम किया है, यह आपके एसपी में मौजूद कई चुनिंदा सूची के रूप में (उदाहरण के रूप में) सौदा करेगा। ध्यान दें कि आप कैसे $ कॉल बंद करने के लिए इससे पहले कि आप फिर से अपने सपा बाहर मानकों को प्राप्त कर सकते हैं ...

?><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><? 

और यह ऊपर कोड से उत्पादन मेरी test_lists सपा का उपयोग कर कैसा दिखता है ...

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