[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: обработка результатов запросов
lucasa
Добрый день всем,

Пишу на php+mysql.

Но никак не могу разрешить свои вопросы, помогите пожалуйста.

Успешное выполнение INSERT, UPDATE, DELETE запросов советуют проверять функцией mysql_affected_rows(), а запрос SELECT - mysql_num_rows().

В итоге если следовать этому совету код у меня выглядит примерно так:

"INSERT INTO...
if(mysql_affected_rows() == 1)
{ SELECT * FROM...
if(mysql_num_rows())
{
"
UPDATE...
if(mysql_num_rows() != 1)
{
$error = true;
}
else
{
$added = true;
}
}

else $error = true;
}
else $error = true;

Т.е. сплошные if'ы.

Плюс, насколько я понимаю, если где-то случилась ошибка, мне нужно самой откатывать всю транзакцию и восстанавливать исходное состояние, а если и тут случится ошибка во время выполнения, тогда что?... замкнутый круг...

Посоветуйте пожалуйста как правильно и эффективно обрабатывать результаты запросов?

И как делать откаты транзакций, какой эффективный способ?

Переходить на ООП плиз не предлагайте, это для меня тееемный лес, не потяну...



Спустя 1 час, 19 минут, 28 секунд (26.01.2011 - 22:54) inpost написал(а):
А что именно ты обновляешь после вставки?

Спустя 9 минут, 54 секунды (26.01.2011 - 23:04) lucasa написал(а):
inpost, другие таблицы...

Спустя 16 минут, 28 секунд (26.01.2011 - 23:21) lovesa написал(а):
хорошо бы было получить весь код с самими запросами и структурой таблиц, плюс логика, что куда и зачем происходит. Песочницы в php и mysql сколько я знаю нет, по этому просто придется оптимизировать код по принципу графов

Спустя 10 минут, 57 секунд (26.01.2011 - 23:32) inpost написал(а):
lovesa
Какие вы похожие =)

lucasa
Покажи этот полный участок. С первого взгляда непонятно что да как =)

Спустя 5 минут, 37 секунд (26.01.2011 - 23:37) lovesa написал(а):
Цитата
Какие вы похожие =)

Да, свезло так свезло =)

Спустя 23 секунды (26.01.2011 - 23:38) lucasa написал(а):
код выкладывать не хотелось бы.
пример выше показала...
логика ничем выдающимся не отличается, стандартный набор любого веб-сервиса...

Спустя 59 секунд (26.01.2011 - 23:39) lucasa написал(а):
inpost, ща, попробую отформатировать

Спустя 1 минута, 33 секунды (26.01.2011 - 23:40) lovesa написал(а):
Цитата
логика ничем выдающимся не отличается, стандартный набор любого веб-сервиса...

В стандартной логике стараются сделать так, что бы был критичный запрос, перед выполнением которого делают всяческие проверки. Редко встречал места где необходимо было бы делать несколько параллельных на столько критичных запроса, что при невыполнении одного пришлось бы откатывать другой =)

Спустя 11 минут, 39 секунд (26.01.2011 - 23:52) lucasa написал(а):
if(isset($_POST['Btn'],$_POST['Id'],$_POST['Result']))
{
$sqlResult = mysql_query("SELECT * FROM `results` WHERE `id`='".mysql_real_escape_string($_POST['Id'])."'");
if(mysql_num_rows($sqlResult) == 1)
{
$result = mysql_fetch_assoc($sqlResult);
if($result)
{
if(mysql_num_rows(mysql_query("SELECT * FROM `result_user_view` WHERE `resultid`='".
mysql_real_escape_string($result['id'])."' AND `status`!='2'")) == $result['total_results_count'])
{
mysql_query("UPDATE `results` SET `status`='2' WHERE `id`='".mysql_real_escape_string($result['id'])."'");
if(mysql_affected_rows() != 1)
{
$error = true;
}
else
{
$added = false;
}
}

else
{
$createdDate = mysql_real_escape_string(gmdate($cfgFormat, time()));
mysql_query("INSERT INTO `result_user_view`(`resultid`,`email`,`result`,`status`,`date`)
VALUES('"
.mysql_real_escape_string($_POST['Id'])."','"
.mysql_real_escape_string($_SESSION['userlogin']).
"','".mysql_real_escape_string($_POST['Result'])."','1','".$createdDate."')");
if(mysql_affected_rows() == 1)
{
mysql_query("UPDATE `results` SET `total_results_count`='".($result['total_results_count']+1)."' WHERE `id`='".mysql_real_escape_string($result['id'])."'");
if(mysql_affected_rows() != 1)
{
$error = true;
}
else
{
$added = true;
}
}

else $error = true;
}
}

else $error = true;
}
}


как-то так...

Спустя 1 минута, 29 секунд (26.01.2011 - 23:53) lucasa написал(а):
lovesa
а критичный запрос один подразумевается?

Спустя 2 минуты, 2 секунды (26.01.2011 - 23:55) lovesa написал(а):
Цитата
а критичный запрос один подразумевается?

один =) но если все же есть нужда рабоать как в песочнице, то есть классная фича как transactions, можно почитать например тут http://www.devarticles.com/c/a/MySQL/Using...QL-4.0-and-PHP/

Спустя 2 минуты, 23 секунды (26.01.2011 - 23:58) lucasa написал(а):
lovesa спасибо)
а альтернативы на русском случайно нет?smile.gif

Спустя 4 минуты, 19 секунд (27.01.2011 - 00:02) lovesa написал(а):
Просмотрел код, не вижу особых мест где откат необходимо делать =) ну по сути в коде присутвует 2 update совершенно в разных местах, update не делается в купе ни с каким запросом, все проверки происходят до самого апдейта, как следствие если где-то что-то сломается или произойдет ошибка, то ничего в базе не изменится.

Спустя 5 минут, 53 секунды (27.01.2011 - 00:08) lovesa написал(а):
Цитата
а альтернативы на русском случайно нет?

по поводу альтернативы, как то в глаза не бросается простой текст на русском, как то везде сучковато описано. huh.gif

Спустя 2 минуты, 54 секунды (27.01.2011 - 00:11) inpost написал(а):
lucasa
1. В int попадает число или значение? Если число, то применяй (int), а не mysql_real_escape_sting.
2. А почему может вдруг не обновиться вторая таблица? Какую именно причину ты видишь? Перегрузки сервера, что на середине скрипта вырубится?

Спустя 6 секунд (27.01.2011 - 00:11) lucasa написал(а):
else
{
$createdDate = mysql_real_escape_string(gmdate($cfgFormat, time()));
mysql_query("INSERT INTO `result_user_view`(`resultid`,`email`,`result`,`status`,`date`)
VALUES('"
.mysql_real_escape_string($_POST['Id'])."','"
.mysql_real_escape_string($_SESSION['userlogin']).
"','".mysql_real_escape_string($_POST['Result'])."','1','".$createdDate."')");
if(mysql_affected_rows() == 1)
{
mysql_query("UPDATE `results` SET `total_results_count`='".($result['total_results_count']+1)."' WHERE `id`='".mysql_real_escape_string($result['id'])."'");
if(mysql_affected_rows() != 1)
{
$error = true;
}
else
{
$added = true;
}
}

else $error = true;
}


Здесь Insert если был, то обязательно должен быть UPDATE. Т.е. если UPDATE не прошел успешно, нужно делать DELETE Insertу...

И один из вопросов у меня был, можно ли как избежать этих многочисленных if'в?

Спустя 4 минуты, 54 секунды (27.01.2011 - 00:16) inpost написал(а):
вполне нормальная вложенность if-else. Не вижу смысла менять что-то.
Ты лучше объясни, чего именно ты боишься и хочешь добиться?

Спустя 34 секунды (27.01.2011 - 00:16) lucasa написал(а):
inpost
сорри, малость не понимаю про какой int идет речь?
Цитата
1. В int попадает число или значение? Если число, то применяй (int), а не mysql_real_escape_sting.



2. у меня знаний не хватает, чтобы судить о возможных проблемах...
как вариант что-то подвиснет...

как вариант сам INSERT INTO может не прокатить и до условия if(mysql_affected_rows() == 1) не дойдет очередь... но это мои преположения

Спустя 24 секунды (27.01.2011 - 00:17) lovesa написал(а):
Я думаю в данном случае тебе помогут транзакции и новая php конструкция исключений - exceptions: http://php.net/manual/en/language.exceptions.php.

работает это как то так: [code]
try {
// начинаем транзакцию
$db->query('BEGIN');

// тут пошли запросы проверки и т.д
$db->query('first query');
$db->query('second query');
$db->query('third query');

// Если добрались до сюда, то подтверждаем изменения
$db->query('COMMIT');
} catch (Exception $e) {
//если была ошибка то
$db->query('ROLLBACK');
}


Но транзакции работают только на таблицах типа innodb

Спустя 2 минуты, 8 секунд (27.01.2011 - 00:19) lucasa написал(а):
inpost
я хотела бы избавиться от этих бесконечных проверок... тут даже assert не напишешь, т.к. просто так оборвать цепочку нельзя...

а боюсь, что что-то помешает выполнится транзакции целиком, т.е. целостность данных попортится...


Спустя 2 минуты, 52 секунды (27.01.2011 - 00:22) lucasa написал(а):
lovesa, спасибо, поизучаю!


у меня такого типа innodb - нет, даже не знаю, что это такое unsure.gif

Спустя 2 минуты, 30 секунд (27.01.2011 - 00:24) lovesa написал(а):
mysql по дефолту если я не ошибаюсь использует тип MyIsam если не ошибаюсь, но при помощи обыкновенного phpmyadmin можно поменять тип таблицы на innodb и спокойно делать rollback`и, если в этом если необходимость. Но тогда данных кусок кода придется немного модифицировать по мануалу exceptions

Спустя 1 минута, 43 секунды (27.01.2011 - 00:26) inpost написал(а):
Если запрос правильный, то врядли целостность будет повреждена.
ты получаешь $result['id'], в ней что содержится, порядковый номер (число) или текстовая строка? Мне кажется, что там число вроде 5, или 8, значит надо вставлять в таблицу так: .(int)$result['id'].
Пойми, пока нету такого, что твой сервер гнётся и хрустит от 10-и тысячного посетителя за последнюю секунду, то нет смысла думать о мелочных оптимизациях. Проверки проходят на первый взгляд логично и правильно, оставляй их такими.
И снова таки, целостность может повредиться только если в одну микросекунды вдруг сервер успеет выйти из строя, что будет врядли.

Просто если ты проектируешь и оптимизируешь сайт зарании известный, что он будет постоянно падать от перенагрузок - то стоит думать, если же обычный сайт, то можно даже не париться над оптимизацией и оставить таким, какой он есть.

Спустя 11 минут, 5 секунд (27.01.2011 - 00:37) lucasa написал(а):
inpost
да, порядковый индекс
(int)$result['id'] - а почему так лучше делать?
просто данные идут из формы, вроде как их лучше обезопасить...

сервер то будет не мой, хз как он будет работать)

в успешном варианте развития, запросов к сайту будет много практически одновременно, хотя сейчас мне это сложно оценить...

Спустя 50 секунд (27.01.2011 - 00:38) lucasa написал(а):
lovesa, да, надо тогда будет почитать про эти таблицы

Спустя 28 минут, 34 секунды (27.01.2011 - 01:06) inpost написал(а):
lucasa
Потому что (int) - для числа, а string - для текстовой строки.

Спустя 9 часов, 38 минут, 50 секунд (27.01.2011 - 10:45) lucasa написал(а):
Меня тут сомнения стали одолевать. В примерах используется код:
if(mysql_affected_rows() > 0)

а я стала использовать сравнение на точное количество обновленных строк:
if(mysql_affected_rows() == 1)

а если в тоже самое время выполнится другой запрос, то эта функция может вернуть совсем иной результат...

как ей правильно пользоваться?

Спустя 2 дня, 4 часа, 59 минут, 36 секунд (1.02.2011 - 15:45) lucasa написал(а):
подниму темку, интересует ответ на последний вопрос, хелп!

Спустя 4 дня, 6 часов, 42 минуты, 55 секунд (5.02.2011 - 22:28) lucasa написал(а):
lovesa
Цитата
Но тогда данных кусок кода придется немного модифицировать по мануалу exceptions

вы имели ввиду мой код или код вашего примера (в зависимости от типа таблицы)?
Быстрый ответ:

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