Подготовленная инструкция PHP MySQL Ошибка соединения - PullRequest
1 голос
/ 06 августа 2011

Обновление: Пожалуйста, смотрите ниже; Я удалил всю абстракцию и создал простой PHP-скрипт, но все равно получаю ту же ошибку. Пожалуйста, смотрите «ДРУГОЕ обновление» ниже для получения дополнительной информации ...

Исходное сообщение: У меня есть запрос, который был правильно сформирован через слой абстракции базы данных. Запрос следующий:

SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id,  
5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email FROM 5c9_dpd_users LEFT JOIN
5c9_dpd_usergroups_cms ON 5c9_dpd_usergroups_cms.id = 5c9_dpd_users.cms_usergroup_id 
ORDER BY username asc

Если я генерирую тот же запрос, но выполняю его как подготовленный оператор, который параметризует второй операнд предложения WHERE, как показано ниже, я получаю неверные результаты. Я уверен, что само утверждение является правильным и что я запускаю подготовку MySQLi. оператор заявления в правильном порядке. Подготовленный запрос заявления ниже:

SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id, 
5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email FROM 5c9_dpd_users LEFT JOIN 
5c9_dpd_usergroups_cms ON 5c9_dpd_usergroups_cms.id = ? ORDER BY username asc

Этот запрос, по-видимому, преобразует 5c9_dpd_users.cms_usergroup_id, который параметризован, в просто '5', поскольку при выполнении запроса извлекаются правильные столбцы из предложения SELECT, но возвращается тот же usergroup_name для всех результатов - это имя группы пользователей соответствует имя группы пользователей для результата, который имеет 5c9_dpd_usergroups_cms.id из 5.

Я связываю параметры динамически (call_user_func_array()). В этом случае я говорю ему связывать параметр ? как i. Я подумал, что, возможно, это заставило его конвертировать 5c9_dpd_users.cms_usergroup_id в 5 по какой-то причине, но я попробовал все три других типа данных (s, b и d) без удачи.

NB. Я много раз использовал свой уровень абстракции базы данных, хотя это первый экземпляр, в котором он запустил соединение (он был разработан только недавно). Повторим, что запрос возвращает правильный результат через PHP и консоль MySQL, если он не параметризован, но если ему дано ? через подготовленные оператором PHP функции, результаты будут неверными, как описано выше.

Если бы кто-нибудь мог помочь, я был бы очень признателен. Я не спал всю ночь, пытаясь найти помощь по этому вопросу, и нигде не могу найти ни одного подобного случая. Спасибо.

Редактировать (предоставляет код PHP):

$stmt->select_prep(array('users.id', 'users.username', 'users.cms_usergroup_id', 'usergroups_cms.usergroup_name', 'users.email'), array('users'));
$stmt->left_join_prep('usergroups_cms');
$stmt->on_prep('usergroups_cms.id', '=', 'users.cms_usergroup_id', 'i');

$stmt->order($column, $asc_desc);
$stmt->execute_prep();

Запрос теперь выполняется, и все, что мне нужно сделать, это вызвать $ stmt-> fetch_prep (), метод обертывания, который в основном извлекает набор результатов. Запрос, который генерирует этот клиентский код, был приведен выше в качестве второго - параметризованного - запроса, который я дал в качестве примера.

Я распечатал некоторый код отладки в моем методе $ stmt-> execute_prep (), и параметр, который привязывается к запросу, выглядит правильно как:

Array
(
  [0] => i
  [1] => 5c9_dpd_users.cms_usergroup_id
)

Это означает, что он связывает один параметр (ключ 1) как int (ключ 0). Я также пытался связать его как строку, двойной тип и блоб, безрезультатно.

ДРУГОЕ Обновление:

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

<?php
$mysqli = new mysqli('localhost', 'root', '', 'frame');

$q = "SELECT ac9_dpd_users.id, ac9_dpd_users.username, ac9_dpd_users.cms_usergroup_id, 
ac9_dpd_usergroups_cms.usergroup_name, ac9_dpd_users.email 
FROM ac9_dpd_users 
LEFT JOIN ac9_dpd_usergroups_cms 
ON ac9_dpd_usergroups_cms.id = ? 
ORDER BY username asc";

$stmt = $mysqli->prepare($q);
$stmt->bind_param('i', $param);
$param = 'ac9_dpd_users.cms_usergroup_id';
$stmt->execute();

$stmt->bind_result($a, $b, $c, $d, $e);

while ($stmt->fetch()) {
    echo "id: $a <br>un: $b <br>id: $c <br>cms name: $d <br>email: $e<br><br>";
}

$stmt->close();
unset($mysqli);
?>

Выход:

id: 7 
un: ADD 
id: 1 
cms name: 
email: test@test.com

id: 1 
un: New User 
id: 2 
cms name: 
email: test@test.com

и т.д.

1 Ответ

1 голос
/ 06 августа 2011

Может быть, я немного придирчив, но я не стал бы начинать имя таблицы / поля с цифры.Используйте букву или окружите эти странные имена обратным трюком (`).Это должно сработать.

Изменить (в соответствии с изменениями вашего вопроса)

Некоторая часть вашего отредактированного скрипта звучит для меня настороженно:

     ...
     ON ac9_dpd_usergroups_cms.id = ? 
     ...
     $stmt->bind_param('i', $param);
     $param = 'ac9_dpd_users.cms_usergroup_id';

Как указано в руководстве по php, mysqli :: prepare принимает параметры в предложении where и не позволяет изменять имя столбца запроса.

Кроме того, выполнение целочисленной привязки строки должнопреобразуйте значение в число, прежде чем вставить его в подготовленный запрос, и ваши $ params должны быть преобразованы в 0.

Выполните инструкцию sqlstate , чтобы проверить, что происходит с запросом сразу после вашеговыполнить:

...
$stmt->execute();
$sqlError = $stmt->sqlstate();
if($sqlError != '00000') die($sqlError);
...

Возможное решение:

<?php
$mysqli = new mysqli('localhost', 'root', '', 'frame');

$q = "SELECT ac9_dpd_users.id, ac9_dpd_users.username, ac9_dpd_users.cms_usergroup_id, 
ac9_dpd_usergroups_cms.usergroup_name, ac9_dpd_users.email 
FROM ac9_dpd_users 
LEFT JOIN ac9_dpd_usergroups_cms 
ON ac9_dpd_usergroups_cms.id = ac9_dpd_users.cms_usergroup_id 
ORDER BY username asc";

$stmt = $mysqli->prepare($q);
$stmt->execute();

$stmt->bind_result($a, $b, $c, $d, $e);

while ($stmt->fetch()) {
    echo "id: $a <br>un: $b <br>id: $c <br>cms name: $d <br>email: $e<br><br>";
}

$stmt->close();
unset($mysqli);
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...