2016-07-13 29 views
0

這裏是我的代碼:我如何知道insert .. select是否實際插入了任何行?

$stm = $dbh 
->prepare("INSERT INTO resend_pass(user_id, token, date_time) 
      SELECT ?, ?, unix_timestamp() 
      FROM dual 
      WHERE NOT EXISTS(SELECT count(*) AS num_week, 
            COALESCE(sum(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 day))),0) as num_day, 
            COALESCE(sum(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 hour))),0) as num_hour, 
            COALESCE(sum(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 minute))),0) as num_1min 
            FROM resend_pass 
           WHERE user_id = ? 
            AND date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 WEEK)) 
           HAVING num_week > 11 OR num_day > 5 OR num_hour > 3 OR num_1min > 0);"); 

if($stm->execute(array(10, 'token', 10))){ 
    echo 'inserted'; 
} else { 
    echo 'failed'; 
} 

我的腳本始終打印inserted,即使沒有行插入。爲什麼?我該如何解決它?

注意到我已經使用this approach來知道它是否成功插入。

回答

-1

INSERT ... SELECTINSERTSELECT所返回的所有行被認爲是成功的;如果SELECT返回零行,則語句將成功插入零行。

要確定如果行已插入,則必須測試受影響行的數量;與PDO這是通過查詢`PDOStatement :: rowCount()方法,如下所示:

try { 
    $stm = $dbh->prepare("INSERT .. SELECT query"); 
    $stm->execute(); 
    if ($stm->rowCount() > 0) { 
     echo 'inserted'; 
    } else { 
     throw new Exception('No rows inserted'); 
    } 
} catch(Exception $e) { 
    echo $e; 
} 
+0

偉大的+1 ..只是你可以請你重寫你的代碼,並使用'try/catch'而不是'if'語句?像這樣'if($ stm-> rowCount()> 0)throw;'。另外*「找不到行」*和*「失敗」*對我來說是完全相同的。 –

+0

難道你不知道PDO可以自行拋出異常嗎? –

+0

另外我想我可以寫'$ stm-> execute(array(10,'token',10))''if'語句,'對嗎? –

1

execute僅當出現錯誤時才返回false。你的腳本回應'插入',因爲沒有錯誤。簡而言之,您的查詢已成功運行。沒有插入,因爲沒有記錄滿足你的SQL的WHERE條款的條件

如果您需要知道行是否實際上是插入,調用rowCount()函數:

if($stm->execute(...)===false): 
    //there was an error 
elseif($stm->rowCount()<1): // $stm->affected_rows if you use MySQLi 
    //no row was inserted 
else: 
    //at least one row was inserted 
endif 

Documentation here.

+0

謝謝,upvote。但我使用PDO,而不是MySQL。 –

+1

我已經編輯了我的答案 – BeetleJuice

+0

PDO拋出異常,因此檢查execute()的結果是相當無意義的 –

相關問題