[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Ошибка в логике запроса
Crater
Задача вроде бы простая. Нужно выбрать из таблицы ряды по двум значениям. Вот так:
		$myrow = mysql_query("SELECT * FROM `bookmarks` WHERE `book_id` = '".$_GET['book']."' AND `user_id` = '".$_SESSION['id']."'") or die(mysql_error());
if (mysql_num_rows($myrow) == 0) {
$ins = mysql_query("INSERT INTO `bookmarks` (`book_id`,`user_id`) VALUES ('".$_GET['book']."', '".$_SESSION['id']."')");
}

То есть одно значение должно равняться тому-то и второе - сему-то. Вот. А он какого-то лешего выбирает ряд даже если совпадает только первое условие. При чём если совпадает только второе - всё нормально. Я уже два часа промудохался на месте :angry: Может ошибка на поверхности, а мне надо проспаться?..



Спустя 1 час, 8 минут, 49 секунд (6.12.2010 - 02:25) kirik написал(а):
Запрос-то правильный. Может правда поспать? :)

UPD
Тут можно сэкономить. Конечно зависит от структуры твоей БД, но обычно можно определить некое уникальное поле (или составной уникальный индекс), и просто делать запрос на вставку.
Потом можно проверить так:
if(mysql_query("INSERT INTO ... SET ...")) {
echo 'запись добавлена';
} else {
if(mysql_errno() == 1062) {
echo 'запись уже существует';
} else {
exit('Произошла ошибка: ' . mysql_error());
}
}

// или так:
mysql_query("INSERT INTO ... SET ...");
$status = mysql_errno();
if($status == 0) {
echo 'запись добавлена';
} elseif($status == 1062) {
echo 'запись уже существует';
} else {
exit('Произошла ошибка: ' . mysql_errno());
}

Про коды ошибок можно почитать тут.

Спустя 9 часов, 54 минуты, 29 секунд (6.12.2010 - 12:20) SlavaFr написал(а):
Цитата (kirik @ 5.12.2010 - 23:25)
Про коды ошибок можно почитать..

А лучше их просто не делать. Т.е допонлнительный запрос как зделал Crater я щитаю правельным. единственное не надо * делать
SELECT 1 FROM `bookmarks` WHERE .... limit 1


Цитата (Crater @ 5.12.2010 - 22:16)
А он какого-то лешего выбирает ряд даже если совпадает только первое условие.

@Crater сними очки, я хочу на твои зрачки посмотреть :)

Спустя 10 часов, 59 минут, 36 секунд (6.12.2010 - 23:19) Crater написал(а):
SlavaFr
Нет, так не пойдёт. $myrow используется мной и дальше в скрипте. Там такое не подходит.
Без очков, special for you smile.gif

И всё равно не работает и всё равно не понимаю почему. Ррррр mad.gif

Спустя 20 минут, 48 секунд (6.12.2010 - 23:40) waldicom написал(а):
Как бы я дебужил (от слова debug) или повесть о программисте.

Итак, для начала вывести результирующий запрос, примерно так:

$query = "SELECT * FROM `bookmarks` WHERE `book_id` = '" . $_GET['book'] . "' AND `user_id` = '" . $_SESSION['id']."'";
echo $query;


После этого выполнить такой запрос через шел или phpmyadmin (или что у Вас под рукой)

Затем, зачем берете в одинарные кавычки значения для полей book_id и user_id? Это ведь наверняка числа?

Потом, надо остерегаться злобных хацкеров и проверять все, что приходит через $_GET (и другие)

Спустя 4 минуты, 29 секунд (6.12.2010 - 23:45) SlavaFr написал(а):
ну тогда зделай так

$myrow = mysql_query($zapros="SELECT * FROM `bookmarks` WHERE `book_id` = '".$_GET['book']."' AND `user_id` = '".$_SESSION['id']."'") or die(mysql_error());
echo $zapros;
if (mysql_num_rows($myrow) == 0) {
$ins = mysql_query($insert="INSERT INTO `bookmarks` (`book_id`,`user_id`) VALUES ('".$_GET['book']."', '".$_SESSION['id']."')");
echo $insert;
}

и теперь покажи запрос который выдает "echo $zapros" и результаты которые в этот запрос по твоему мнению не вписываются.

Спустя 22 минуты, 30 секунд (7.12.2010 - 00:07) Crater написал(а):
SQL запрос выдаёт такую вот замарочку:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO `bookmarks` (`book_id`,`user_id`) VALUES ('2', '47') LIMIT 0, 30' at line 2

Сказать по правде, я до сих пор не очень понимаю, в чём загвоздка. Значения принимает правильные... unsure.gif

waldicom
Всё верно, а числа нельзя в одинаковые кавычки брать?

Ну, в плане защиты от подлецов у меня пока полная прорва. Радует, что защищать по сути ещё и нечего. А вообще надо, конечно.

Спустя 21 минута, 39 секунд (7.12.2010 - 00:29) waldicom написал(а):
Цитата (Crater @ 6.12.2010 - 23:07)
use near 'INSERT INTO `bookmarks` (`book_id`,`user_id`) VALUES ('2', '47') LIMIT 0, 30'

А для чего нужен LIMIT в INSERT ?

Цитата (Crater @ 6.12.2010 - 23:07)
Всё верно, а числа нельзя в одинаковые кавычки брать?

Можно. Но не нужно, они же числа. Но mysql ничего против не имеет (если не в strict mode)

Спустя 32 минуты, 44 секунды (7.12.2010 - 01:01) kirik написал(а):
Цитата (SlavaFr @ 6.12.2010 - 04:20)
А лучше их просто не делать. Т.е допонлнительный запрос как зделал Crater я щитаю правельным. единственное не надо * делать

Как показывает практика "как правильно" не всегда "как лучше".
В случае с двумя запросами мы: во-первых сделаем один лишний запрос, и потеряем с ним время, а если таблица часто обновляется да еще и myisam, так мы вообще будем 2 раза ждать. Во-вторых возможен вариант "race condition", когда между выборкой и вставкой вклинится запрос на вставку из другого потока, тогда получится таже самая ошибка, вот только как-то не ожиданно smile.gif Иначе нужно объединять эти запросы в транзакцию.

Спустя 12 часов, 34 минуты, 42 секунды (7.12.2010 - 13:36) SlavaFr написал(а):
Цитата (kirik @ 6.12.2010 - 22:01)
Иначе нужно объединять эти запросы в транзакцию.

Против трансакции и "select for update" не имею не чего против, а вот ошибки лучше не делать, нечего лог-файл пачкать.

@Crater спасибо что снял очки. Вроде бы зрачки нормальные biggrin.gif

Спустя 7 часов, 56 минут, 41 секунда (7.12.2010 - 21:33) kirik написал(а):
Цитата (SlavaFr @ 7.12.2010 - 05:36)
нечего лог-файл пачкать

Насколько мне известно, ошибочные запросы не логируются сервером БД. На уровне приложения конечно может логироваться, но не в случае ТС smile.gif

Спустя 1 день, 35 минут, 3 секунды (8.12.2010 - 22:08) Crater написал(а):
SlavaFr
tongue.gif
waldicom
Вообще я лимит не вводил, но это не помешало ему появиться в окончательном запросе почему-то.
Но дело не в этом. Дело в том, что для отдельно взятого значения user_id может быть море записей. А вот для отдельно взятой book_id - одна. Поэтому стоит мне удалить запись, как пользователь, который ещё недавно никак не мог вставить запись, тут же без проблем это делает. Короче говоря book_id судя по всему у меня уникальный. Хотя вроде бы я его таким не делал. Пересоздал таблицу - помогло... мне точно надо больше спать. Всем спасибо!


_____________
Цитата
Я не потерпел неудачу. Я просто нашел десять тысяч способов, которые не работают.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.