Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: PDO запрос

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: разный результат
imper
Отправлено: 01 Октября, 2014 - 12:45:12
Post Id



Частый гость


Покинул форум
Сообщений всего: 134
Дата рег-ции: Февр. 2012  
Откуда: Тольятти


Помог: 2 раз(а)

[+]


Добрый день.

щас приведу пример что бы был понятен этот бред, у меня в базе 11 записей, одна запись уже "добавлена" , вообщем остаётся 10 записей которые должны мне вывестись при загрузке страницы и ничего не должно подгружаться когда я прокручиваю страницу вниз (аякс подзагрузка при прокрутке страницы стоит)
но почему то у меня подгружается эта 11 запись, когда LIMIT 10,20

проверяю sql запрос в phpmyadmin'е всё нормально выводит

если обрамлять в phpmyadmin'е NOT IN ('77,101,....') то ведёт себя так же как и запрос в php скрипте, в чём же проблема ? О_о

PHP:
скопировать код в буфер обмена
  1.   $id_user = intval($_SESSION['id']);
  2.   $cur = intval($_POST['cursor']);
  3.   $get_data_sel_msg = $_POST['sel'];
  4.   $tems = strval($_SESSION['connect_tems']);//в сессии хранится строка вида 77,23,11,...
  5.  



есть запрос
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT chat_tema.id,chat_tema.id_user,chat_tema.tema, chat_tema.count, chat_tema.date, chat_tema.img,profile_user.name_user, profile_user.family_user
  3.         FROM  friends_iv,chat_tema,profile_user
  4.         WHERE chat_tema.id NOT IN(:tems) AND (friends_iv.id_user_ot = :id_us1 OR friends_iv.id_user_pol = :id_us2) AND friends_iv.readed = 1
  5.         AND ( (friends_iv.id_user_ot = :id_us3 AND friends_iv.id_user_pol =  chat_tema.id_user) OR (friends_iv.id_user_ot =  chat_tema.id_user AND friends_iv.id_user_pol = :id_us4 ) )
  6.         AND profile_user.id = chat_tema.id_user
  7.         ORDER BY chat_tema.id DESC LIMIT :cursor,20
  8.  


вообщем обратите внимание на NOT IN (:tems)

вот сдесь я вставляю все данные

PHP:
скопировать код в буфер обмена
  1. $sth = $db->pdo_obj->prepare($sql_osn);
  2. $sth->bindParam(':id_us1', $id_user , PDO::PARAM_INT);
  3.  
  4. $sth->bindParam(':tems'  , $tems    , PDO::PARAM_STR);
  5. $sth->bindParam(':id_us2', $id_user , PDO::PARAM_INT);
  6. $sth->bindParam(':id_us3', $id_user , PDO::PARAM_INT);
  7. $sth->bindParam(':id_us4', $id_user , PDO::PARAM_INT);
  8. $sth->bindParam(':cursor', $cur    , PDO::PARAM_INT);
  9.        
  10. $sth->execute();
  11. echo json_encode($sth->fetchAll());//отправляю клиенту
  12.  


вообщем вставляю я всё правильно всё работает просто не пойму почему мне эта 11 запись продгружается

(Отредактировано автором: 01 Октября, 2014 - 12:47:25)



-----
Самое лучшее решение проблемы
самое простое
 
 Top
esterio
Отправлено: 01 Октября, 2014 - 12:55:59
Post Id



Активный участник


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


Помог: 127 раз(а)




PDO не может подставить в prepare в оператор IN строку
нужно делать
CODE (SQL):
скопировать код в буфер обмена
  1.  NOT IN(:tems0, :tems1 ...)

а в PHP
PHP:
скопировать код в буфер обмена
  1. $sth->bindParam(':tems0'  , $tems[0]    , PDO::PARAM_STR);
  2. $sth->bindParam(':tems1'  , $tems[1]    , PDO::PARAM_STR);
  3. // ...

ну и вместо строкы держать массив
PHP:
скопировать код в буфер обмена
  1. $_SESSION['connect_tems'] = array(77, 23, ...)
 
 Top
Мелкий Супермодератор
Отправлено: 01 Октября, 2014 - 13:05:20
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




imper пишет:
$sth->bindParam(':id_us1', $id_user , PDO::PARAM_INT); 
$sth->bindParam(':id_us2', $id_user , PDO::PARAM_INT);
$sth->bindParam(':id_us3', $id_user , PDO::PARAM_INT);
$sth->bindParam(':id_us4', $id_user , PDO::PARAM_INT);

Это не имеет смысла, PDO умеет один параметр корректно подставлять в запросе несколько раз.
Т.е. можно спокойно писать where user_id_from=:id_us or user_id_to=:id_us и биндить только id_us

По теме - да, IN препарированным запросом делать неудобно.
Если делать field in (:var) и биндить значения через запятую, то и получится field in ('значения через запятую'), что эквивалентно field = 'значения через запятую'
Т.е. смысла не имеет.
Надо делать field in (:var1, :var2, ...) и биндить отдельно значения.


-----
PostgreSQL DBA
 
 Top
imper
Отправлено: 01 Октября, 2014 - 13:08:55
Post Id



Частый гость


Покинул форум
Сообщений всего: 134
Дата рег-ции: Февр. 2012  
Откуда: Тольятти


Помог: 2 раз(а)

[+]


Ну теперь понятно, просто интересно почему он не может в NOT IN обычную строку впихнуть?

я просто вместо параметра :tems вставил в запрос переменную напрямую

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT chat_tema.id,chat_tema.id_user,chat_tema.tema, chat_tema.count, chat_tema.date, chat_tema.img,profile_user.name_user, profile_user.family_user
  2.         FROM  friends_iv,chat_tema,profile_user
  3.         WHERE chat_tema.id NOT IN($tems) AND (friends_iv.id_user_ot = :id_us1 OR friends_iv.id_user_pol = :id_us2) AND friends_iv.readed = 1
  4.         AND ( (friends_iv.id_user_ot = :id_us3 AND friends_iv.id_user_pol =  chat_tema.id_user) OR (friends_iv.id_user_ot =  chat_tema.id_user AND friends_iv.id_user_pol = :id_us4 ) )
  5.         AND profile_user.id = chat_tema.id_user
  6.         ORDER BY chat_tema.id DESC LIMIT :cursor,20


-----
Самое лучшее решение проблемы
самое простое
 
 Top
esterio
Отправлено: 01 Октября, 2014 - 13:36:04
Post Id



Активный участник


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


Помог: 127 раз(а)




для ответа нужно знать как оно работает, а эт ен 5 минут. думаю вам стоит поискать в гугле
 
 Top
Мелкий Супермодератор
Отправлено: 01 Октября, 2014 - 13:46:41
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




imper пишет:
просто интересно почему он не может в NOT IN обычную строку впихнуть?

Именно что строку и вставляет. А вам-то не нужна строка, вам нужны пачка параметров с разделителем-запятой. А получается один элемент - строка.


-----
PostgreSQL DBA
 
 Top
teddy
Отправлено: 01 Октября, 2014 - 18:22:24
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




А все таки вопрос можно решить и без отдельного биндинга.

Идея в том, что бы подставлять в запрос не именованные параметры, а вопросики, которые PDO скушает и не подавится.

Для начала нужно понимать, что для того что бы использовать такух схему, вам нужен отдельный массив данных с теми значениями, которые должны быть подставлены в IN, и отдельный массив данных, значения из которого будут использоваться в WHERE, AND и т.п
Почему? Должно быть ясно по коду.

PHP:
скопировать код в буфер обмена
  1. $params = array(1,2,3);//массив, в котором лежает данные для IN
  2. $data = array(1);//массив, который содержит данные для условий в запросе
  3.  
  4. $inParams = rtrim(str_repeat('?,', count($params)), ',');//генерим вопросики для IN
  5. $allParams = array_merge($data, $params);//соединяем данные для условий и IN
  6.  
  7. $stmt = $dbh->prepare('SELECT `some`,`columns` FROM `table` WHERE `col` > ? AND `id` IN('.$inParams.')');
  8. $stmt->execute($allParams);


Порядок передаваемых значений в array_merge должен быть именно таким.
 
 Top
esterio
Отправлено: 01 Октября, 2014 - 18:26:23
Post Id



Активный участник


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


Помог: 127 раз(а)




ну тогда теряеться возможность именных плейсхолдеров
 
 Top
teddy
Отправлено: 01 Октября, 2014 - 18:32:47
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




esterio
Ну и пусть Улыбка Не вижу проблем... В конечном счете это никак не влияет на выполнение запроса
 
 Top
Мелкий Супермодератор
Отправлено: 01 Октября, 2014 - 18:36:05
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




esterio пишет:
ну тогда теряеться возможность именных плейсхолдеров

Не теряется.
Ничто не мешает с совершенно тем же результатом сформировать in (:mydata1, :mydata2, ..) и скормить execute ассоциативный массив с mydata1=>$data1, mydata2=>$data2
Это одно и то же.

Проблема в том, что это именно биндинг отдельных элементов и есть. Вопросиками или именованными параметрами - без разницы.


-----
PostgreSQL DBA
 
 Top
teddy
Отправлено: 01 Октября, 2014 - 18:53:45
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




Мелкий
В принципе да, отдельный биндинг все равно так или иначе должен быть.
Этот способ лишь попытка уйти от явного и неоднократного вызова метода bindParam.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB