2016-07-13 1 views
0

Вот мой код:Как я могу узнать, если вставить .. 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 ... SELECT считается успешным, когда он INSERT s все строки, возвращенные SELECT; если 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' statement? Подобно этому 'if ($ stm-> rowCount()> 0) throw;'. Также * «Нет строк найдено» * и * «не удалось» * для меня идентичны. –

+0

Разве вы не знаете, что PDO может самостоятельно генерировать исключения? –

+0

Также я думаю, что могу написать '$ stm-> execute (array (10, 'токен, 10))' из этого 'if' оператора, правильно? –

1

execute возвращение false только если была ошибка. Ваш скрипт эхо вставлен, потому что ошибки не было. Короче говоря, ваш запрос был успешно выполнен. Ничего не было вставлено, потому что запись не выполнил условия в WHERE пункте вашего SQL в

Если вам нужно знать, был ли на самом деле вставляется строка, вызовите 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() совершенно бессмысленно –

0

Как насчет используя функцию mysqli_affected_rows() http://php.net/manual/es/mysqli.affected-rows.php

Если вы используете PDO (я думаю, это ваш случай), вы можете попробовать $stm->rowCount().

Подготовленные операторы возвращают количество затронутых строк с помощью этого метода.

+1

Да, я думаю, 'rowCount()' это то, что я ищу. спасибо upvote. –