Проблемы при использовании нескольких подготовленных MySQLi операторов - PullRequest
0 голосов
/ 21 января 2012

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

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

2: оператор if ((int) $ check <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 голос
/ 23 января 2012
  1. LIMIT работает ... он ограничивает количество возвращаемых строк и вашу возвращаемую 1 строку только одним полем (просто считать), так что LIMIT в конце бессмысленно, потому что в любом случае он вернет один результат. Кроме того, почему в вашей команде UPDATE есть LIMIT 1?
  2. Вы можете использовать INSERT ON DUPLICATE KEY UPDATE и создать УНИКАЛЬНЫЙ индекс для ваших столбцов: ach_class, user_id, и все будет в порядке.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...