2016-07-13 32 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()的结果是相当无意义的 –

相关问题