2010-11-26 47 views
1

這實際上是my earlier question today的派生項。在foreach循環中調用存儲過程 - 僅首次執行

我在我的數據庫中創建了一個存儲過程,我想從PHP中連續調用多次。
比方說,這是我的方法:

CREATE PROCEDURE PROC_1(
    IN param1 VARCHAR(255), 
    IN param2 VARCHAR(255)) 
BEGIN 
    DECLARE ok INT; 
    DECLARE success, failure VARCHAR(255); 

    /* several SELECT, IF ... THEN, INSERT and UPDATE operations which then SET ok var to 0 or 1 */ 
    IF ok = 1 THEN 
    SET success = 'Everything went well'; 
    SELECT success; 
    LEAVE; 
    ELSE 
    SET failure = 'Problem description'; 
    SELECT failure; 
    LEAVE;  
    END IF; 
END 

我就是這麼做的(短版):

$calls = array(
    "CALL PROC_1('param1', 'param2')", 
    "CALL PROC_1('param3', 'param4')", 
    "CALL PROC_1('param5', 'param6')", 
); 

// assuming I'm already connected to DB with $link 
foreach ($calls as $i => $call) 
{ 
    echo $i . ': '; 
    $result = mysql_query($call); 
    $ok = ($result === FALSE) ? FALSE : TRUE; 
    var_dump($ok); 

    if ($result !== FALSE) 
     mysql_free_result($result); 
} 

第一次迭代按預期工作,但回報FALSE後什麼。
這是爲什麼?

試圖mysqli以防萬一,但恰好有相同的輸出:

0: bool(true) 
1: bool(false) 
2: bool(false) 

有趣的,我檢查MySQL的日誌(日誌記錄設置爲記錄所有查詢)和只有第一個查詢還未獲得服務器。接下來的查詢永遠不會到達服務器。

PS。我運行PHP 5.3.2和Apache 2.2.17。


UPDATE

按沙克蒂·辛格的建議,我查詢數據庫之前檢查$link狀態。我注意到有一個錯誤,因爲第二次迭代所以這裏有錯誤的輸出:

ERROR: (0) 
0: bool(true) 
ERROR: (0) 

ERROR: (0) 
1: bool(false) 
ERROR: (2014) Commands out of sync; you can't run this command now 

ERROR: (2014) Commands out of sync; you can't run this command now 
2: bool(false) 
ERROR: (2014) Commands out of sync; you can't run this command now 

而且,這似乎在MySQL錯誤日誌:

101126 15:46:28 [Warning] Aborted connection 129 to db: 'db1' user: 'root' host: 'localhost' (Got an error reading communication packets) 
+0

你可以var_dump($ link)在echo $ i之下。 ':'; – 2010-11-26 14:07:10

回答

2

在php中,當我們在一個循環中調用一個存儲過程時,它只執行一次。它在存儲過程返回任何結果集時發生。 我面臨同樣的問題。我有一個更新表記錄的存儲過程。

DELIMITER $$ 

DROP PROCEDURE IF EXISTS `espritkm`.`update_notification`$$ 
CREATE DEFINER=`root`@`localhost` PROCEDURE `update_notification`(item_id_val VARCHAR(11),item_source_val VARCHAR(50),item_type_id_val INT(50),item_type_val VARCHAR(50),created_at_val BIGINT(11),pivot_user_id_val VARCHAR(256),pivot_item_type_val VARCHAR(64),pivot_owner_type_val VARCHAR(64),pivot_owner_id_val INT(11),user_id_val VARCHAR(64), OUT row_effect VARCHAR(11)) 
Begin 
    Declare item_count INT(10); 
    SET @SQL1 = CONCAT('select count(*) into @item_count from item_notifications where item_id = ''', item_id_val, '''');                     PREPARE S1 FROM @SQL1;                    EXECUTE S1;                     DEALLOCATE PREPARE S1;  
    IF @item_count = 0 THEN 
     SET @SQL2 = CONCAT('INSERT INTO item_notifications (item_id,item_source,item_type_id,item_type,created_at,pivot_user_id,pivot_item_type,pivot_owner_type,pivot_owner_id,user_id) value(''',item_id_val,''',''',item_source_val,''',''',item_type_id_val,''',''',item_type_val,''',''',created_at_val,''',''',pivot_user_id_val,''',''',pivot_item_type_val,''',''',pivot_owner_type_val,''',''',pivot_owner_id_val,''',''',user_id_val,''')');  
PREPARE S2 FROM @SQL2;                     EXECUTE S2;                      DEALLOCATE PREPARE S2;  
     SET row_effect= "Insert";  
    ELSE    
     SET row_effect= "Update";  

    SET @SQL3 = CONCAT('UPDATE item_notifications SET viewer_id = ''',user_id_val,''' WHERE item_id = ''' ,item_id_val,'''') ;  
     PREPARE S3 FROM @SQL3;                     EXECUTE S3;                     DEALLOCATE PREPARE S3;  

    END IF; 
    SELECT row_effect; 
END$$ 

DELIMITER ; 

而這應該是爲1000 +行執行,但只執行一條記錄。

它不支持您的SP何時返回任何數據集。只要消除OUT var或任何select語句(僅用於任何結果引用),它就可以正常工作。