2012-01-21 5 views
0

Я пытаюсь вставить и обновить данные, используя 3 подготовленных оператора. Происходит две проблемы:Проблемы при использовании нескольких подготовленных операторов mysqli

1: запрос SELECT COUNT проверяет, существует ли запись с LIMIT 1 и результат хранится в $ check. Тем не менее, LIMIT 1, кажется, игнорируется, например, когда у меня есть три строки, соответствующие условиям WHERE в SELECT COUNT, $ check возвращает 3 вместо 1.

2: Ошибка if ((int) $ < 1) и всякий раз, когда $ check = 0, я вижу вывод из моего эха, однако $ stmt_insert-> execute(); и $ stmt_total-> execute(); фактически не вставляют и не обновляют базу данных.

Но, когда я закомментировать:

$stmt_check->execute(); 
$stmt_check->bind_result($check); 
$stmt_check->fetch(); 

тогда $ stmt_insert и $ stmt_total работы и строки вставляются и обновляются. Мне интересно, есть ли способ заставить все три утверждения работать должным образом, потому что, похоже, какой-то конфликт возникает с моей текущей настройкой. Спасибо за ваше время.

Вот полный код:

$user_id = 100; 
$count = preg_match_all("#<li>(.*?)</li>#is", $html, $matches, PREG_SET_ORDER); 

$stmt_check = $mysqli->stmt_init(); 
$stmt_check->prepare("SELECT COUNT(`user_id`) AS `check` FROM `ua` WHERE `ach_class` = ? AND `user_id` = ? LIMIT 1"); 
$stmt_check->bind_param('si', $ach_class, $user_id); 

$stmt_insert = $mysqli->stmt_init(); 
$stmt_insert->prepare("INSERT INTO `ua` (`user_id`, `ach_class`, `time_log`) VALUES (?, ?, ?)"); 
$stmt_insert->bind_param('isi', $user_id, $ach_class, $ach_timestamp); 

$stmt_total = $mysqli->stmt_init(); 
$stmt_total->prepare("UPDATE `ach` SET `total` = `total` +1 WHERE `ach_class` = ? LIMIT 1"); 
$stmt_total->bind_param('s', $ach_class); 

for ($i = 0; $i < $count; $i++) { 
    $li_block = $matches[$i][1]; 
    preg_match('#img/(.*?)_60.png#is', $li_block, $class_matches); 
    $ach_class = $class_matches[1]; 
    $ach_class = substr($ach_class, 11, -11); 

    $ach_timestamp = time(); 

    $stmt_check->execute(); 
    $stmt_check->bind_result($check); 
    $stmt_check->fetch(); 
    echo $ach_class.' --- Check = '.$check.'<br />'; 

    if ((int)$check < 1) { 
     $stmt_insert->execute(); 
     echo 'insert<br />'; 

     $stmt_total->execute(); 
     echo 'update<br />'; 
    } else { 
     echo 'already present<br />'; 
    } 
} 

$stmt_insert->close(); 
$stmt_check->close(); 
$stmt_total->close(); 

ответ

1
  1. LIMIT работает ... это ограничивает количество возвращаемых строк, и ваше возвращение 1 строку только с одним полем (только в счет), так что предел в конец является своего рода бессмысленным, так как в любом случае он вернет единый результат. Кроме того, почему у вас есть LIMIT 1 в вашей команде UPDATE?
  2. Вы можете использовать INSERT ON DUPLICATE KEY UPDATE и создать индекс UNIQUE в своих столбцах: ach_class, user_id, и все будет в порядке.
Смежные вопросы