[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Как поместить запрос в цикл?
Strannik
Здравствуйте. Хочу поместить проверку значения ram в цикл. Пишу:
    connect();  
$ram=mt_rand(10, 15);
do{
$sql = "SELECT * FROM `one` WHERE `ram` = '$ram'";
$result = mysql_query($sql);
$ram=mt_rand(10, 15);
} while (mysql_num_rows($result) > 0);


Однако попадаю на
mysql_num_rows(): supplied argument is not a valid MySQL result resource

Подскажите как выйти из данной ситуации.



Спустя 12 минут, 11 секунд (15.01.2011 - 09:59) sergeiss написал(а):
Цитата (Strannik @ 15.01.2011 - 10:46)
Подскажите как выйти из данной ситуации.

1. Забыть всё, что ты написал.
2. Сделать правильно.

Это если кратко.

Спустя 3 минуты, 48 секунд (15.01.2011 - 10:02) Strannik написал(а):
это понятно) но как написать правильно, пробовал не получается('

можно конечно написать через
if ((mysql_num_rows($result)>0)
{$ram=mt_rand(10,15)}
но это не то, мне нужна множественная проверка, на случай если второе случайное число тоже будет в бд...

Спустя 4 минуты, 8 секунд (15.01.2011 - 10:07) sergeiss написал(а):
Ты для начала опиши, что ты хочешь получить smile.gif А потом уж можно будет говорить о том, как это сделать.
И в любом случае надо стремиться избегать запросов в цикле. Только если уж в самом крайнем случае.

Спустя 5 минут, 7 секунд (15.01.2011 - 10:12) Strannik написал(а):
1)мне нужно присвоить рендомное значение от 10 до 15 переменной $ram
2)нужно проверить существует ли это значение в бд
3)если существует сделать новый рендом для переменной и снова на проверку
4)если не существует, то записать в бд

но как это можно правильно сделать?..

Спустя 4 часа, 22 минуты, 1 секунда (15.01.2011 - 14:34) sergeiss написал(а):
А чуть подробнее - с какой целью?

Может, проще сразу ввести в БД эти 5 значений и выбирать произвольное из них, причем изначально ставить метку, что оно не было выбрано ранее, а при выборке ставить сию метку? Вот это можно будет сделать одним запросом.

Спустя 51 минута, 18 секунд (15.01.2011 - 15:25) Strannik написал(а):
Цитата (sergeiss @ 15.01.2011 - 14:34)
А чуть подробнее - с какой целью?

Может, проще сразу ввести в БД эти 5 значений и выбирать произвольное из них, причем изначально ставить метку, что оно не было выбрано ранее, а при выборке ставить сию метку? Вот это можно будет сделать одним запросом.

Цель - проверка на уникальность (как идентификатор товара)

может проще...
навряд ли потому как всего значений около 1000 и необходим рендом...

Спустя 30 минут, 17 секунд (15.01.2011 - 15:55) sergeiss написал(а):
Цитата (Strannik @ 15.01.2011 - 16:25)
Цель - проверка на уникальность (как идентификатор товара)

Ничё не понял... А при чем тут рандом тогда??????

Ты все-таки опиши имеющуюся у тебя задачу. Потому что просто для проверки уникальности вовсе на надо таких "изыскоФФ" wink.gif, которые ты делаешь.

Спустя 28 минут, 9 секунд (15.01.2011 - 16:23) twin написал(а):
    do
{

mysql_query("INSERT IGNORE INTO `one`
SET `ram` = "
. mt_rand(10, 15);
);

}
while(mysql_affected_rows() < 1);
Только поле ram сделай уникальным

Спустя 54 секунды (15.01.2011 - 16:24) twin написал(а):
Вообще это чушь, послушай sergeiss

Спустя 4 часа, 58 минут, 36 секунд (15.01.2011 - 21:23) Strannik написал(а):
описание
1) мне нужно присвоить случ число переменной $ram
2) нужно записать $ram в бд, причем если значение $ram уже есть в бд, нужно выбрать присвоить переменной $ram другое случ число

Пример:
----случ число 1324($ram='1324';).
----Мне нужно проверить существует ли число 1324 в бд;
----Если число 1324 уже есть в бд, мне нужно присвоить переменной $ram другое случ число(например $ram='5435';).
----И снова проерку на существование значения $ram в бд (пока не окажется, что значение $ram отсутствует в бд)
----Если значение переменной $ram отсутствует в бд, нужно записать значение переменной $ram в бд.

Спустя 6 минут, 24 секунды (15.01.2011 - 21:29) inpost написал(а):
Strannik
$ram=mt_rand(10, 15); - помести внутрь do,
перед ним создай $temp = 0;
внутри давай параметр $temp = mysql_num_rows;
а while проверяй ($temp > 0)

Спустя 13 минут, 22 секунды (15.01.2011 - 21:43) twin написал(а):
Я же написал рабочий код))) Чего вы мудрите?

Спустя 4 минуты, 54 секунды (15.01.2011 - 21:48) sergeiss написал(а):
Цитата (twin @ 15.01.2011 - 22:43)
Я же написал рабочий код))) Чего вы мудрите?

Да, но вот эти твои слова
Цитата (twin @ 15.01.2011 - 17:24)
Вообще это чушь, послушай sergeiss

выглядят так, как камент к предыдущим твоим словам, тем, где код есть smile.gif

Вот он и не слушает тебя wink.gif

Спустя 11 минут, 1 секунда (15.01.2011 - 21:59) inpost написал(а):
twin
Мне твой пример показался немного сложноватым =) Поэтому я просто обозначил ошибку ТС, которая может исправить, а не изменить его скрипт и сделать рабочим =)

Спустя 19 минут, 29 секунд (15.01.2011 - 22:18) Arni написал(а):
Мне даже трудно себе представить для чего это может сгодиться. Есть же автоинкримент, который при добавлении записи в базу данных 100% гарантирует уникальность значения. Если вам потом в последствии нужно изять случайную запись то такое для серверов баз данных тоже имеется.

Ну да ладно, не нам понимать зачем нужно и.т.д.


Однозначно рекомендую задействовать подготовку запроса перед его выполнением. Если имеется расширение php mysqli то стоит почитать документацию.

http://php.net/manual/en/book.mysqli.php

Почитав все это можно сообразить код.


//=> Подключаем базу данных
$db = new mysqli($db['hostname'], $db['nameuser'], $db['password'], $db['namebase']);

//=> Подготовка запроса
$stmt = $alexa->prepare('INSERT IGNORE INTO my_tab
SET ram = ?'
);

do{
$rand = mt_rand(0, 10000);
$stmt->bind_param('i',$rand);
}while(!$stmt->execute());

$stmt->close();


Столбец таблицы ram отмечаем как уникальные значения.

Если я ничего не путаю, база данных будет возвращать ошибку потому что прошла попытка добавить строку с дублируемым значением. И цикл будет повторяться до тех пор пока этот запрос не проскочит.

Подготовка запроса перед выполнением в цыкле ускорит скорость итерации.


Опять же повторюсь, зачем это надо? Ведь есть вероятность что при огромном количестве записей в базе этот цыкл будет долго работать :).


Мне кажется что автор темы плохо продумал путь к решению своей задачи.

Спустя 4 минуты, 9 секунд (15.01.2011 - 22:22) sergeiss написал(а):
Цитата (Arni @ 15.01.2011 - 23:18)
Мне кажется что автор темы плохо продумал путь к решению своей задачи.

Об этом ему было сказано сразу же... Но у него особое мнение smile.gif

Спустя 4 минуты, 51 секунда (15.01.2011 - 22:27) inpost написал(а):
Arni
Да нет, отличный скрипт-губитель.
Представь, когда заносится первое значение? В первый день работы сайта, цикл пройдет 1 раз и будет 1 обращение.
Через месяц при должном посещении один скрипт выполняеться будет уже секунду. И через пол годика можно ждать клиента с вопросами "что случилось, сайт еле работает"? А ты ему заявляешь: "Понимаете, сайт есть сайт, а работа над оптимизацией при огромных посещениях - это другое!". Накрутили счётчик *10, *100. И всё. Клиент ведётся и платит деньги за оптимизацию.
За минуту можно зарабатывать 100-200 $ (стереть этот скрипт-губитель) + сотрудничество с хостерами, как бы ты приводишь к ним жирного клиента, который со временем перейдёт на более дорогие пакеты (а тебе %). Да + ещё будет благодарность от сеошника, ведь ему хвала и похвалы за такой наплыв людей =)

Теперь осталось добавить пункт в договор: "Работа над оптимизацией высоконагруженных проектов при огромном посещении оплачивается дополнительно", а можно эту надпись в доп.услуги студии добавить серым цветом =)

Спустя 16 минут, 32 секунды (15.01.2011 - 22:44) Snus написал(а):
Strannik
Что за проект у тебя с такими задачами? smile.gif Если ты расскажешь - тебе будет легче помочь.

Спустя 8 минут, 16 секунд (15.01.2011 - 22:52) twin написал(а):
Arni

Цитата
Почитав все это можно сообразить код.

Чем он принципиально отличается от моего? biggrin.gif
Зачем так все усложнять?

Ну а человек решает какую то свою хитрую задачу, всех заинтриговал и не колется.

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

С числами никаких разумных вариантов в голову не идет((

Спустя 14 минут, 24 секунды (15.01.2011 - 23:06) Snus написал(а):
twin
Мне почему-то в голову сразу лезет лотерея типа "Выкатывается шар и его номер ... 5673!" %)

Спустя 39 минут, 16 секунд (15.01.2011 - 23:46) Arni написал(а):
Цитата (twin @ 15.01.2011 - 19:52)
Arni

Цитата
Почитав все это можно сообразить код.

Чем он принципиально отличается от моего? biggrin.gif
Зачем так все усложнять?
((

Тем что работает намного быстрее smile.gif. НО как уже подметил inpost, ту наоборот надо в цикл вставить sleep(10);. Иначе денег с клиента потом за оптимизацию не получится выбить.


Кстати мне тоже жутко интересно что за пентагоновский секрет.

Спустя 9 минут, 9 секунд (15.01.2011 - 23:55) inpost написал(а):
Arni
Даже без sleep при посещений 200-300 в сутки база забьется, если до 10 000 или до 100 000 делать макс. число. Оно будет ооочень долго искать пустое место =)

Спустя 19 минут, 11 секунд (16.01.2011 - 00:14) twin написал(а):
Цитата
Arni
Тем что работает намного быстрее
Уверен? Я вот склонен сомневаться...

Спустя 24 минуты, 45 секунд (16.01.2011 - 00:39) Arni написал(а):
Цитата (twin @ 15.01.2011 - 21:14)
Цитата
Arni
Тем что работает намного быстрее
Уверен? Я вот склонен сомневаться...



<?php
define('TIMESTART',microtime()); // Время старта
$db['hostname'] = "*****"; // Хост
$db['nameuser'] = "*****"; // Пользователь
$db['password'] = "*****"; // Пароль
$db['namebase'] = "*****"; // Имя БД

//=> Подключаем базу данных

$db = new mysqli($db['hostname'], $db['nameuser'], $db['password'], $db['namebase']);

//=> Подготовка запроса
$stmt = $db->prepare('SELECT id
FROM al_page
WHERE id = ?'
);
for($i = 0; $i < 100; $i++){
$rand = mt_rand(20, 30);
$stmt->bind_param('i',$rand);
$stmt->bind_result($id);
$stmt->fetch();
$stmt->execute();
}
$stmt->close();

$start = explode(' ',TIMESTART);
$start = $start[0] + $start[1];
$end = microtime();
$end = explode(' ',$end); $end = $end[0] + $end[1];
echo substr(number_format($end - $start,4),0,6);
?>




<?php
define('TIMESTART',microtime()); // Время старта
$db['hostname'] = "*****"; // Хост
$db['nameuser'] = "*****"; // Пользователь
$db['password'] = "*****"; // Пароль
$db['namebase'] = "*****"; // Имя БД

//=> Подключаем базу данных

$db = new mysqli($db['hostname'], $db['nameuser'], $db['password'], $db['namebase']);


for($i = 0; $i < 100; $i++){
$result = $db->query('SELECT id
FROM al_page
WHERE id = '
.mt_rand(20, 30).'');
$row = $result->fetch_assoc();
}


$start = explode(' ',TIMESTART);
$start = $start[0] + $start[1];
$end = microtime();
$end = explode(' ',$end); $end = $end[0] + $end[1];
echo substr(number_format($end - $start,4),0,6);
?>


Та шоб я провалился :)

Спустя 2 часа, 23 минуты, 17 секунд (16.01.2011 - 03:02) Strannik написал(а):
теперь разобрался=)

Спасибо всем за помощь

Спустя 5 часов, 28 минут, 8 секунд (16.01.2011 - 08:30) twin написал(а):
Arni
Цитата
define('TIMESTART',microtime());
true пропустил.

А вобще я не понял, что за тест и что ты сравниваешь.

Я не поленился и тоже проверил. Во первых, твой код не рабочий. А во вторых, вот корректный тест:
<?php

$db['hostname'] = "localhost"; // Хост
$db['nameuser'] = "root"; // Пользователь
$db['password'] = ""; // Пароль
$db['namebase'] = "test"; // Имя БД

$mysqli = new mysqli($db['hostname'], $db['nameuser'], $db['password'], $db['namebase']);


$start = microtime(true); // Время старта
//=> Подготовка запроса

$stmt = $mysqli->prepare('INSERT IGNORE INTO al_page
SET ram = ?'
);
$i = 0;
do{
$rand = ++$i;
$stmt->bind_param('i', $rand);
$stmt->execute();
}while($mysqli->affected_rows == 0);

printf('%.5f с', microtime(true) - $start);

$stmt->close();

?><br /><?php

mysql_connect($db['hostname'], $db['nameuser'], $db['password']);
mysql_select_db($db['namebase']);

$start = microtime(true); // Время старта
$i = 0;
do
{
$rand = ++$i;
mysql_query("INSERT IGNORE INTO al_page
SET `ram` = "
. $rand
);
}
while(mysql_affected_rows() == 0);

printf('%.5f с', microtime(true) - $start);

Дамп в аттаче. Посмотри сам.
В принципе это и было очевидно.

Спустя 3 часа, 15 минут, 17 секунд (16.01.2011 - 11:45) Arni написал(а):
Цитата (twin @ 16.01.2011 - 05:30)
Arni
Цитата
define('TIMESTART',microtime());
true пропустил.

А вобще я не понял, что за тест и что ты сравниваешь.

Я не поленился и тоже проверил. Во первых, твой код не рабочий. А во вторых, вот корректный тест:

Код однозначно рабочий я же дал ссылки на результат его работы. Резве что при копировании что-то повредилось. В тесте 1 у нас идет подготовленный запрос и потом в цыкле его выполнение. Второй тест запрос уходит обычным способом. Сравнивать нужно время выполнения скрипта. Первый работает быстрее. И чем больше запросов тем это лучше видно. Что косается вашего теста то он менее справедливый поскольку в одном примере вы все сделали через ООП, а второй обычными функциями. smile.gif

Спустя 2 часа, 23 минуты, 2 секунды (16.01.2011 - 14:08) twin написал(а):
Цитата
Код однозначно рабочий

Я имел ввиду первый код. А он не рабочий по двум причинам. Первая - опечатка

$db = new mysqli($db['hostname'], $db['nameuser'], $db['password'], $db['namebase']);
//=> Подготовка запроса
$stmt = $alexa->prepare('INSERT IGNORE INTO my_tab
SET ram = ?');

Вторая серьёзнее. Дело в том, что при таком раскладе $stmt->execute() никогда не вернет false, так как запрос считается успешным. Пусть даже ничего не изменилось в таблице, но запрос то проходит нормально.

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

Ну а с чего весь сыр бор))) Я ведь не просто так спросил:
Цитата
Зачем так все усложнять?

Спустя 1 час, 27 минут, 17 секунд (16.01.2011 - 15:36) Arni написал(а):
В таком случае разобрались smile.gif.
Быстрый ответ:

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