$wpdb->get_results(...) возвращает пустой массив, несмотря на правильный запрос

22 сент. 2014 г., 08:14:28
Просмотры: 18K
Голосов: 9

Как следует из заголовка, я не могу получить результаты через $wpdb->get_results. "Сырой" запрос выполняется успешно, но по какой-то странной причине этот метод не работает.

    global $wpdb;


    $sql = "SELECT *
            FROM что-то aki, 
                 что-то-еще akb, 
                 что-то-еще-еще ac 
            WHERE aki.keyID = akb.keyID 
              AND akb.someID = ac.someID 
              AND aki.type LIKE '%что-то%'";

    $corps = $wpdb->get_results($sql, OBJECT);

    var_dump($corps);
9
Комментарии

Вы пробовали выполнить этот запрос напрямую в phpmyadmin?

TBI Infotech TBI Infotech
22 сент. 2014 г. 08:15:31

Да, и в phpmyadmin, и напрямую в mysql shell. В обоих случаях работает. Но $wpdb->get_results возвращает пустой массив.

1Up 1Up
22 сент. 2014 г. 08:40:15

Не могу точно определить проблему. Но вы можете отладить это, используя запрос без второго параметра OBJECT, начав с простого запроса и постепенно добавляя условия. Так вы сможете выяснить проблему.

TBI Infotech TBI Infotech
22 сент. 2014 г. 08:49:04

Дополняя комментарий @TBIInfotech, вы не забыли использовать префикс WP для своих таблиц, где это уместно?

Joshua Joshua
22 сент. 2014 г. 09:25:09

Йо-хо-хо... Я просто использовал $wpdb->show_errors( true ) перед запросом и получил ошибку. Похоже, WP внезапно начал кодировать символ ' в запросах без видимой причины... Возможно, это причина и ваших проблем тоже. Может быть, стоит передавать '%thing%' как параметр в get_reults.

NoOne NoOne
27 февр. 2016 г. 21:44:42

В итоге моя проблема оказалась в том, что мне следовало использовать $wpdb->posts вместо wp_posts в запросе. Похоже, что по какой-то непонятной причине таблицы БД на нашем сервере были переименованы? WTF?!?!?!

NoOne NoOne
27 февр. 2016 г. 22:03:10

@NoOne Если вы решили эту проблему, пожалуйста, опубликуйте ответ и примите его :) (это уберет этот вопрос из списка неотвеченных). Всегда используйте префикс таблиц, а не полагайтесь на то, что он всегда будет wp_

Tim Malone Tim Malone
28 июн. 2016 г. 01:42:03

@TimMalone Это не мой вопрос, поэтому я не могу его принять. Но я опубликую ответ. Возможно, это поможет некоторым людям... ;)

NoOne NoOne
30 июн. 2016 г. 19:35:10

@NoOne Ха-ха, совершенно верно. Спасибо, что опубликовали ответ! Как раз пытаюсь разобраться со списком неотвеченных вопросов ;)

Tim Malone Tim Malone
30 июн. 2016 г. 22:24:00
Показать остальные 4 комментариев
Все ответы на вопрос 5
0

Используйте $wpdb->show_errors( true ) перед запросом и посмотрите, какая ошибка вернется.

Моя проблема (потому что я сталкивался с тем же) заключалась в том, что мне нужно было использовать $wpdb->posts вместо wp_posts внутри запроса. Префикс таблиц может меняться от установки к установке WordPress или даже в одной установке в зависимости от времени (например, администратор может изменить префикс, когда захочет). Поэтому запрос следует писать так:

$query = "select <stuff here> from $wpdb->posts where <stuff here>";
27 февр. 2016 г. 21:46:48
5

Я разбирался со своим скриптом, который выдавал пустой массив в WordPress, несмотря на, казалось бы, корректную MySQL строку. Оказалось, что, в отличие от автора вопроса, я использовал $wpdb->prepare(), но решение, которое я нашёл, может быть полезным для тех, кто столкнётся с этим Q&A (как это случилось со мной).

В этой строке, AND aki.type LIKE '%thing%'", содержатся подстановочные знаки процента (%), которые указывают, что мы ищем ячейку aki.type, содержащую thing как часть своего значения.

$wpdb->prepare преобразует их в хэши, и MySQL сервер получает что-то вроде этого: AND aki.type LIKE '{399038939300d2c307c53b29a166ee90101da7b2aba7978a898694010bf1bfe6}thing{399038939300d2c307c53b29a166ee90101da7b2aba7978a898694010bf1bfe6}'. Естественно, результаты будут отсутствовать!

На странице wpdb::prepare сказано: 'Буквальные знаки процента (%) в строке запроса должны быть записаны как %%. Подстановочные знаки процента (например, для использования в синтаксисе LIKE) должны передаваться через аргумент подстановки, содержащий полную строку LIKE, они не могут быть вставлены напрямую в строку запроса. Также см. wpdb::esc_like().'

Таким образом, часть LIKE должна быть подготовлена следующим образом (пример из страницы wpdb::esc_like()):

$wild = '%';
$find = 'only 43% of planets';
$like = $wild . $wpdb->esc_like( $find ) . $wild;
$sql  = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like );

Где $wpdb->esc_like() должен вызываться перед $wpdb->prepare().

А если нужно вручную заменить подстановочные знаки процента, следует использовать $wpdb->remove_placeholder_escape() после $wpdb->prepare().

14 июн. 2022 г. 10:18:21
Комментарии

Я публикую это здесь, потому что запрос в вопросе очень похож на тот, что был у меня, и не сразу было очевидно, что в моем случае проблема была в $wpdb->prepare(). Я полагаю, что кто-то еще может попасть на эту страницу с такой же проблемой.

Artem Artem
14 июн. 2022 г. 10:24:40

Ваша проблема в чем-то похожа, но не идентична исходному вопросу. Я предлагаю создать новый вопрос и затем ответить на него (ответы на собственные вопросы приветствуются). Затем вы можете отметить свой ответ как принятый, и люди, у которых возникли проблемы с $wpdb->prepare() (в отличие от $wpdb->get_results()), смогут легче найти ваш вопрос и ответ.

Pat J Pat J
14 июн. 2022 г. 18:08:12

Принято, Pat J. Как вы думаете, мне стоит оставить этот ответ здесь или удалить его?

Artem Artem
14 июн. 2022 г. 18:55:22

Я бы сказал, оставьте как есть. Если администратор посчитает это неуместным, он может удалить.

Pat J Pat J
14 июн. 2022 г. 20:44:50

готово https://wordpress.stackexchange.com/q/406772/190417

Artem Artem
15 июн. 2022 г. 06:58:01
3

Возможно, это немного запоздало, но вам не хватает вызова "prepare", необходимого в WordPress:

$Table_Name    = $wpdb->prefix.'Your Table Name';
$sql_query     = $wpdb->prepare("SELECT * FROM $Table_Name WHERE aki.keyID=%d AND akb.someID=%d AND aki.type like %s", akb.keyID, ac.someID, ''%thing%');
$result        = $wpdb->query( $sql_query ); 

Множественные результаты могут быть найдены в массиве.

6 мар. 2019 г. 01:27:14
Комментарии

Он упомянул, что ранее указал неправильное имя таблицы. Вызов $wpdb->prepare() не требуется для запроса, который полностью статичен и не формируется пользователем, поэтому здесь это вряд ли поможет. В любом случае, ваша строка prepare() выше содержит код, который не является PHP.

Brian C Brian C
11 апр. 2020 г. 07:31:20

Для числовых поисков нет... но для строковых поисков в mySQL требуется другой способ передачи параметров, который обеспечивает вызов prepare(). Иначе вам придётся вручную добавлять '%s%' вокруг строки. Если этого не сделать, поиск в mysql завершится ошибкой.

Debbie Kurth Debbie Kurth
13 апр. 2020 г. 00:49:30

Верно, но вы неверно поняли. "Статичный" означает неизменяемый, т.е. запрос, полностью основанный на фиксированном тексте, без подставляемых переменных. Показанный запрос был фиксированным текстом (т.е. "статичным"), поэтому использование prepare ничего не даёт. Однако хорошей практикой является использование prepare() при подстановке значений в запрос (т.е. для динамических или нестатичных запросов). Удачи.

Brian C Brian C
13 апр. 2020 г. 10:04:04
0

У меня была такая же проблема - правильный SQL-запрос, никаких ошибок, но отсутствие результатов при использовании wpdb.

Решение для меня заключалось в правильной кодировке/сопоставлении (например, COLLATE 'utf8_general_ci') для моей таблицы.

У меня был запрос, который работал, но после замены таблицы на дамп с другого сервера (более старого сервера) мой запрос перестал работать. Он возвращал NULL или 0, хотя при выполнении запроса непосредственно в базе данных возвращались правильные результаты.

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

Когда таблица была создана таким образом, мой запрос НЕ работал:

CREATE TABLE IF NOT EXISTS `vf_user` (
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `email` varchar(50) NOT NULL,
  `full_name` varchar(25) NOT NULL,
  `password` varchar(25) NOT NULL,
  `role` enum('user','tester','admin') NOT NULL DEFAULT 'user',
  `phone` varchar(25) NOT NULL,
  `last_modified` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  `user_activation_key` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=325 DEFAULT CHARSET=utf8 COMMENT='users table';

А когда таблица была создана таким образом, мой запрос возвращал результаты:

CREATE TABLE `vf_user` (
    `id` MEDIUMINT(9) NOT NULL AUTO_INCREMENT,
    `email` VARCHAR(50) NOT NULL COLLATE 'utf8_general_ci',
    `full_name` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
    `password` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
    `role` ENUM('user','tester','admin') NOT NULL DEFAULT 'user' COLLATE 'utf8_general_ci',
    `phone` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
    `last_modified` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
    `user_activation_key` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
    PRIMARY KEY (`id`) USING BTREE,
    UNIQUE INDEX `email` (`email`) USING BTREE
)
COMMENT='users with access to the virtual festival'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=325
;
25 нояб. 2020 г. 12:05:48
0

Функция Wpdb->get_results в WordPress возвращает результат, если запрос выполнен успешно, в противном случае она вернет null. Существует множество причин, по которым запрос может завершиться неудачно. Подробнее о диагностике можно прочитать в статье get_results() возвращает пустые результаты здесь.

Хотя вы можете использовать такие функции, как wpdb->show_error(), чтобы проверить последнюю ошибку после выполнения SQL-запроса. Иногда эта ошибка возвращает пустое значение, тогда попробуйте использовать wpdb->last_query, чтобы проверить окончательный сформированный запрос.

6 авг. 2021 г. 20:24:08