#php #mysqli
#php #mysql #mysqli #mysql-insert-id #sql
Вопрос:
Когда я запускаю следующий код, я получаю сообщение об ошибке
Неустранимая ошибка: неперехваченное исключение ‘mysqli_sql_exception’ с сообщением ‘Индекс не используется в запросе / подготовленном операторе’
$mysql = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die('There was a problem connecting to the database');
if (mysqli_connect_errno()) {
printf("DB error: %s", mysqli_connect_error());
exit();
}
$get_emp_list = $mysql->prepare("SELECT id, name FROM calc");
if(!$get_emp_list){
echo "prepare failedn";
echo "error: ", $mysql->error, "n";
return;
}
$get_emp_list->execute();
$get_emp_list->bind_result($id, $emp_list);
И это подходящая схема —
--
-- Table structure for table `calc`
--
CREATE TABLE IF NOT EXISTS `calc` (
`id` int(12) NOT NULL,
`yr` year(4) NOT NULL,
`mnth` varchar(12) NOT NULL,
`name` varchar(256) NOT NULL,
`paidleave` int(12) NOT NULL,
`balanceleave` int(12) NOT NULL,
`unpaidleave` int(12) NOT NULL,
`basesalary` int(12) NOT NULL,
`deductions` int(12) NOT NULL,
`tds` int(12) NOT NULL,
`pf` int(12) NOT NULL,
`finalsalary` int(12) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Ответ №1:
Неустранимая ошибка не в MySQL; уведомление об отсутствии индекса является предупреждением относительно низкой степени серьезности.
Фатальная ошибка находится в вашем PHP-коде из-за следующих трех условий:
- mysqli выдает много предупреждений даже для относительно безвредных условий.
- Вы вызываете
mysqli_sql_exception
все ошибки и предупреждения из-за вашейmysqli_report(MYSQLI_REPORT_ALL);
строки. - Ваш PHP-код не улавливает это исключение (т. Е. Оно не находится в
try{}
блоке с соответствующимcatch(){}
блоком), и неперехваченные исключения являются фатальными.
Вы ничего не можете сделать с первым, как упоминалось в другом ответе. Итак, вы можете исправить это, либо изменив свой mysqli_report(...)
параметр на MYSQLI_REPORT_STRICT
или MYSQLI_REPORT_OFF
, либо на что-либо другое, кроме MYSQLI_REPORT_ALL
.
(редактировать: комментарий w3d ниже дает хорошее объяснение, почему, и предлагает использовать mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
в качестве хорошей альтернативы)
Для получения наилучших практик и в сочетании с этим вы должны исправить это должным образом, используя try{}
и catch(){}
соответствующим образом в своем коде.
Комментарии:
1. Это часто имеет низкую степень серьезности, но не следует пренебрегать: в сообщении говорится, что сервер mysql должен выполнить полное сканирование таблицы, т. Е. Должен проверять каждую запись, принадлежит ли она к результирующему набору или нет. В случае большой базы данных может помочь дополнительный индекс к искомым столбцам.
2. В частности, чтобы удалить эти конкретные предупреждения, вам необходимо удалить
MYSQLI_REPORT_INDEX
флаг изreport_mode
свойства. Этот флаг «Сообщает, если в запросе не использовался индекс или неверный индекс». Итак, используйтеmysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
вместо mysqli_report (MYSQLI_REPORT_ALL)` перед выполнением вашего запроса.
Ответ №2:
mysqli_report(MYSQLI_REPORT_ALL ^ MYSQLI_REPORT_INDEX);
Отключает «Отчет, если в запросе не использовался индекс или неверный индекс», но сохраняет другие отчеты.
Ответ №3:
Взгляните на этот отчет об ошибке: расширение #35450
mysqli сообщает о слишком большом количестве предупреждений
Цитирую несколько предложений примечания :
Расширение Mysqli выдает слишком много предупреждений.
Например, «ВЫБРАТЬ * ИЗ таблицы» выдает предупреждение: «Предупреждение: mysqli::query(): нет индекса, используемого в запросе / подготовленном операторе ВЫБЕРИТЕ * ИЗ таблицы …»
И, цитируя другое примечание, которое кажется интересным :
Используйте
mysqli_report()
, чтобы отключить это.
Комментарии:
1. Хммм… Я не думаю, что это устарело, так как я использую его очень хорошо .. mysqli_report (MYSQLI_REPORT_ALL);
2. Устаревший не означает «не работает», но «больше не должен использоваться и может быть удален в один прекрасный день»
3. Верно, но то, что у меня есть, это не предупреждение, это фатальная ошибка. Я хотел бы знать о фатальных ошибках.
4. Он не должен был быть устаревшим (похоже, это было случайно): bugs.php.net/bug.php?id=55329
5. Да, это все еще допустимая команда в PHP7, без сообщения об устаревании в документах: php.net/manual/en/function.mysqli-report.php
Ответ №4:
сообщение «Индекс не используется в запросе / подготовленном операторе» относится не к вашему коду PHP, а к дизайну вашей таблицы, просто ДОБАВЬТЕ индекс в вашу таблицу.
действительно, лучше всего включить ошибку / предупреждения в DEVELOP:
mysqli_report(MYSQLI_REPORT_ALL);
но отключается в рабочей среде:
mysqli_report(MYSQLI_REPORT_STRICT);
Ответ №5:
Другой способ исправить это — сделать столбец таблицы ‘name’ в MySQL индексом.
ALTER TABLE `calc` ADD INDEX ( `name` ) ;
Комментарии:
1. Этого недостаточно, если у вас небольшая таблица. В этом случае MySQL / MariaDB неявно отключит индексы в таблице и объединит это с выбрасыванием mysqli, если индексы не используются, у вас будет приятный беспорядок при выравнивании звездочек 🙂 «Работает в prod, не работает в staging / dev».