Корректно ли составлен запрос?
Верно (корректно) ли составлен запрос ?
function connectDB() { try { $errorMessage = 'Ошибка подключения к базе данных'; $DB = 'mysql:host='.DB_HOST.';dbname='.DB_NAME; $conn = new PDO($DB, DB_USER, DB_PASSWORD); $conn ->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); return $conn; } catch(PDOException $e) { file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND); throw new Exception($errorMessage); } } function getParameters($default = '') { $data = [ 'surname' => isset($_POST['surname']) ? trim(mb_strtolower($_POST['surname'])) : $default, 'name' => isset($_POST['name']) ? trim(mb_strtolower($_POST['name'])) : $default, 'fathername' => isset($_POST['fathername']) ? trim(mb_strtolower($_POST['fathername'])) : $default, 'phone' => isset($_POST['phone']) ? trim(preg_replace('/[^0-9,+]/', '',($_POST['phone']))) : $default, 'email' => isset($_POST['email']) ? trim(mb_strtolower($_POST['email'])) : $default, ]; return $data; } function checkPeople($data,$conn){ $query = "SELECT * FROM `orders2022` WHERE LOWER(`surname`) LIKE CONCAT('%', ?, '%') AND LOWER(`name`) LIKE CONCAT('%', ?, '%') AND LOWER(`fathername`) LIKE CONCAT('%', ?, '%')"; $stmt = $conn -> prepare ($query); $stmt->execute([$data['surname'], $data['name'], $data['fathername']]); $result = $stmt->fetch(PDO::FETCH_ASSOC); } |
function connectDB() { try { $errorMessage = 'Ошибка подключения к базе данных'; $DB = 'mysql:host='.DB_HOST.';dbname='.DB_NAME; $conn = new PDO($DB, DB_USER, DB_PASSWORD); $conn ->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); return $conn; } catch(PDOException $e) { file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND); throw new Exception($errorMessage); } } function getParameters($default = '') { $data = [ 'surname' => isset($_POST['surname']) ? trim(mb_strtolower($_POST['surname'])) : $default, 'name' => isset($_POST['name']) ? trim(mb_strtolower($_POST['name'])) : $default, 'fathername' => isset($_POST['fathername']) ? trim(mb_strtolower($_POST['fathername'])) : $default, 'phone' => isset($_POST['phone']) ? trim(preg_replace('/[^0-9,+]/', '',($_POST['phone']))) : $default, 'email' => isset($_POST['email']) ? trim(mb_strtolower($_POST['email'])) : $default, ]; return $data; } function checkPeople($data,$conn){ $query = "SELECT * FROM `orders2022` WHERE LOWER(`surname`) LIKE CONCAT('%', ?, '%') AND LOWER(`name`) LIKE CONCAT('%', ?, '%') AND LOWER(`fathername`) LIKE CONCAT('%', ?, '%')"; $stmt = $conn -> prepare ($query); $stmt->execute([$data['surname'], $data['name'], $data['fathername']]); $result = $stmt->fetch(PDO::FETCH_ASSOC); }
Дополнительно:
$query = "SELECT * FROM `orders2022` WHERE LOWER(`surname`) LIKE CONCAT('%', ?, '%') AND LOWER(`name`) LIKE CONCAT('%', ?, '%') AND LOWER(`fathername`) LIKE CONCAT('%', ?, '%')"; |
$query = "SELECT * FROM `orders2022` WHERE LOWER(`surname`) LIKE CONCAT('%', ?, '%') AND LOWER(`name`) LIKE CONCAT('%', ?, '%') AND LOWER(`fathername`) LIKE CONCAT('%', ?, '%')";
Если синтаксически - корректно.
Но если в техническом задании нет описания, как именно вы собираетесь искать заказы за 2022 год, то сказать определенно корректно, или определенно некорректно - сложно.
так как из POST вы извлекаете еще почту и телефон, которые в запросе не применяются.
.$errorMessage
А это вообще зачем в данном месте?
Я вижу, что оно не используется, но логически, если будет использоваться, почему оно там?
Ответы:
Мне необходимо только узнать есть ли такой заказчик с такими данными.
1) Оформляйте запрос строками, так будет гораздо проще и вам, и другим разработчикам понять что вы пишете и как оно работает:
SELECT * FROM `orders2022` WHERE LOWER(`surname`) LIKE CONCAT('%', ?, '%') AND LOWER(`name`) LIKE CONCAT('%', ?, '%') AND LOWER(`fathername`) LIKE CONCAT('%', ?, '%') |
SELECT * FROM `orders2022` WHERE LOWER(`surname`) LIKE CONCAT('%', ?, '%') AND LOWER(`name`) LIKE CONCAT('%', ?, '%') AND LOWER(`fathername`) LIKE CONCAT('%', ?, '%')
2) Синтаксис верный, но если вам важно найти "хоть одно совпадение", лучше использовать LIMIT 1, это остановит базу в поиске всех вхождений, то есть перебора ВСЕЙ таблицы вместо выхода по первому вхождению. Кроме того, CONCAT('%', ?, '%') можно использовать если вместо ? будет SQL выражение (например каой-то селект), в данном случае это просто трата ресурса процессора. Просто добавьте % в начале и конце подставляемой переменной.
3) Неплохо давать более четкое описание проблемы, чтобы другим не пришлось гадать о чем код, так как никто кроме вас в контекст задачи не погружен.
Если сформулировать вопрос так: необходимо узнать есть заказ от заказчика с полученными ФИО, номером телефона или эл. почты на определённую дату.
С учётом замечаний, запрос приобрёл вид:
function connectDB() { try { $DB = 'mysql:host='.DB_HOST.';dbname='.DB_NAME; $conn = new PDO($DB, DB_USER, DB_PASSWORD); $conn ->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); return $conn; } catch(PDOException $e) { $errorMessage = 'Ошибка подключения к базе данных'; file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND); throw new Exception($errorMessage); } } function getParameters($default = '') { $data = [ 'surname' => isset($_POST['surname']) ? trim(mb_strtolower("%{$_POST['surname']}%")) : $default, 'name' => isset($_POST['name']) ? trim(mb_strtolower("%{$_POST['name']}%")) : $default, 'fathername' => isset($_POST['fathername']) ? trim(mb_strtolower("%{$_POST['fathername']}%")) : $default, 'phone' => isset($_POST['phone']) ? trim(preg_replace('/[^0-9,+]/', '',($_POST['phone']))) : $default, 'email' => isset($_POST['email']) ? trim(mb_strtolower($_POST['email'])) : $default, 'date' => isset($_POST['date']) ? trim(mb_strtolower($_POST['date'])) : $default, ]; return $data; } function checkPeople($data,$conn){ $query = "SELECT * FROM `orders` WHERE ((LOWER(`surname`) LIKE ? AND LOWER(`name`) LIKE ? AND LOWER(`fathername`) LIKE ?) OR (LOWER(`email`) LIKE ?) OR (`phone` LIKE ?)) AND (`date` = ?) LIMIT 1"; $stmt = $conn -> prepare ($query); $stmt->execute([$data['surname'], $data['name'], $data['fathername']], $data['email'], $data['phone'], $data['date']); $result = $stmt->fetch(PDO::FETCH_ASSOC); } |
function connectDB() { try { $DB = 'mysql:host='.DB_HOST.';dbname='.DB_NAME; $conn = new PDO($DB, DB_USER, DB_PASSWORD); $conn ->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); return $conn; } catch(PDOException $e) { $errorMessage = 'Ошибка подключения к базе данных'; file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND); throw new Exception($errorMessage); } } function getParameters($default = '') { $data = [ 'surname' => isset($_POST['surname']) ? trim(mb_strtolower("%{$_POST['surname']}%")) : $default, 'name' => isset($_POST['name']) ? trim(mb_strtolower("%{$_POST['name']}%")) : $default, 'fathername' => isset($_POST['fathername']) ? trim(mb_strtolower("%{$_POST['fathername']}%")) : $default, 'phone' => isset($_POST['phone']) ? trim(preg_replace('/[^0-9,+]/', '',($_POST['phone']))) : $default, 'email' => isset($_POST['email']) ? trim(mb_strtolower($_POST['email'])) : $default, 'date' => isset($_POST['date']) ? trim(mb_strtolower($_POST['date'])) : $default, ]; return $data; } function checkPeople($data,$conn){ $query = "SELECT * FROM `orders` WHERE ((LOWER(`surname`) LIKE ? AND LOWER(`name`) LIKE ? AND LOWER(`fathername`) LIKE ?) OR (LOWER(`email`) LIKE ?) OR (`phone` LIKE ?)) AND (`date` = ?) LIMIT 1"; $stmt = $conn -> prepare ($query); $stmt->execute([$data['surname'], $data['name'], $data['fathername']], $data['email'], $data['phone'], $data['date']); $result = $stmt->fetch(PDO::FETCH_ASSOC); }
Надеюсь верно)
- Логически все верно, единственный вопрос - что за неуловимый Джо у вас клиент, с совпадением как по более-менее уникальным полям типа емэйла и телефона, так и по имени, которое вообще не уникально, да еще и писаться может по разному (например содержать диакритики и их будет лень вводить, иии короче много нюансов ))...). Особо интересует именно двухсторонний % в лайк условии, что заставляет БД выключить индекс и перебирать в режиме фуллскан (т.е. читать все записи в таблице перебором)... Там где у вас четкое совпадение можно (и нужно) использовать "=", дату переводить в нормальный формат и тоже использовать "=".
- ThunderCat, Согласен по ФИО лишнее с учётом того что email и phone обязательные и более-менее уникальные поля. Знания по бд в зачаточном состоянии, изучаю). Спасибо большое за замечания.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для того чтобы определить корректность составленного запроса, необходимо учитывать несколько важных аспектов. Вот некоторые из них:
1. Синтаксическая правильность: Убедитесь, что запрос не содержит опечаток, лишних символов или ошибок в синтаксисе. Проверьте правильность написания ключевых слов, операторов и имен переменных.
2. Логическая правильность: Проверьте, что запрос соответствует вашим ожиданиям и целям. Убедитесь, что логика запроса верна и он делает то, что вы от него ожидаете.
3. Безопасность: Проверьте, что ваш запрос защищен от SQL-инъекций и других видов атак. Используйте параметризованные запросы или экранирование данных, чтобы предотвратить возможные уязвимости.
4. Эффективность: Оцените производительность запроса и убедитесь, что он выполняется быстро и эффективно. Используйте индексы, оптимизацию запросов и другие методы для улучшения скорости выполнения.
Если вы уверены, что ваш запрос соответствует всем перечисленным выше критериям, то можно считать его корректно составленным. В противном случае, пройдите через каждый из аспектов и внесите необходимые изменения для улучшения запроса. Не стесняйтесь задавать вопросы и запрашивать помощь у сообщества, если у вас возникли сложности с составлением запроса.