#php #mysql
#php #mysql
Вопрос:
Итак, у меня есть функция, которая генерирует случайное число в базе 62, и я хотел бы попытаться вставить случайное уникальное число длиной 7 в таблицу. Изначально у меня было автоматическое увеличение строк по мере ввода значений, но для этого требовалось много вставок, выбора, а затем обновления строк. Вот новый код, который пока не работал:
do {
if (isset($query)) { mysqli_stmt_close($query); }
$query = mysqli_prepare($connection, "INSERT INTO table1 value1=?");
mysqli_stmt_bind_param($query, 's', rand_64(7));
} while (!mysqli_stmt_execute($query));
mysqli_stmt_close($query);
Мой вопрос: можно ли достичь чего-то подобного, или было бы лучше сгенерировать случайные числа, попробовать оператор SELECT, и если возвращаемые строки == 0, прекратить цикл и вставить значения?
Редактировать: я должен отметить, что он правильно вставляет значения, если значение уникально (т. Е. Его еще нет в таблице), но не может вставить, если значение уже существует.
Большое спасибо. 🙂
Комментарии:
1. Вы пробовали
ON DUPLICATE KEY
илиINSERT IGNORE
?2. Сколько из них вы должны вставить? Это одноразовое требование или вам нужно будет делать это повторно?
3. Фред: В этом случае, вероятно, не сработал бы ДУБЛИРУЮЩИЙ КЛЮЧ, потому что мне нужно было бы знать, какое число генерируется. Майк: Пользователь загружает файлы, и это переименовывает их с помощью генератора случайных строк, чтобы к ним можно было позже подключиться. Конечная цель — продолжать цикл и пытаться вставить, пока не произойдет столкновения.
4. будут ли ‘uniqid’ и ‘base_convert’ или ‘base64_encode’ делать то, что вы хотите?
Ответ №1:
Вот простой способ присвоить случайное уникальное значение каждой строке в таблице:
SET @r = 0;
UPDATE table1
SET value1 = (@r:=@r 1)
ORDER BY RAND();
Вы получаете значения от 1 до количества строк в таблице, но значения распределяются псевдослучайно, а не увеличиваются, как при автоинкременте.
Ответ №2:
Вы не можете привязать результат вызова функции или литерал к подготовленному оператору — это должна быть переменная. Если вы присвоите возвращаемое значение rand_64()
переменной перед ее привязкой, у вас должно быть больше успеха.
Кроме того, вам нужно подготовить запрос только один раз, чтобы вы могли вывести его из цикла.
Это дает вам:
if (isset($query)) { mysqli_stmt_close($query); }
$query = mysqli_prepare($connection, "INSERT INTO table1 set value1=?");
do {
$rand = rand_64(7)
mysqli_stmt_bind_param($query, 's', $rand);
} while (!mysqli_stmt_execute($query));
mysqli_stmt_close($query);
Все это говорит о том, что, поскольку вы генерируете переменную самостоятельно и, скорее всего, потребуется только один вызов базы данных, вы, вероятно, получите лучшую общую производительность, не используя здесь подготовленный оператор.
Предполагая, что ваша rand_64()
функция не возвращает никаких строк, содержащих одинарные кавычки, вы получаете:
$success = true;
do {
$rand = rand_64(7)
$query = "INSERT INTO table1 set value1='$rand'";
if (mysqli_query($connection, $query)) == true) {break;}
if (mysqli_error($connection) != 1062) {
$success = false;
break;
}
} while (true);
NB:
- Я исправил синтаксическую ошибку в вашем SQL
- ваш
value1
должен быть помечен как уникальный, ненулевой. - Я еще не тестировал этот код.
Комментарии:
1. Спасибо за помощь. Я пробовал этот код, и он должен сработать, потому что mysqli_query возвращает true / false, верно? Но когда я это делаю, он помещает себя в бесконечный цикл. Есть какие-нибудь идеи, что может происходить?
2. Ваш исходный SQL-запрос был неправильным и сгенерировал синтаксическую ошибку, поэтому цикл будет продолжаться вечно. Я исправил свой фрагмент и добавил проверку цикла на разрыв, если ошибка не является дубликатом.