Форум русской поддержки Joomla!® CMS
17.08.2017, 12:06:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
   
   Начало   Поиск Joomla 3.0 FAQ Joomla 2.5 FAQ Joomla 1.5 FAQ Правила форума Новости Joomla Реклама Войти Регистрация Помощь  
Основной курс по Joomla
Страниц: [1]   Вниз
  Добавить закладку  |  Печать  
Автор

SQL изменение поля и получения результата

 (Прочитано 193 раз)
0 Пользователей и 1 Гость смотрят эту тему.
avantyrist
Давно я тут
****

Репутация: +3/-0
Offline Offline

Пол: Мужской
Сообщений: 230



« : 11.03.2017, 22:57:04 »

Добрый день.
Выполняю такой код:


Код:
$db = JFactory::getDBO();
$query = "
UPDATE `#__table_name`
  SET count = @new_count  := count +1
  WHERE `field` = 'my_field';
SELECT @new_count;
     ";
$db->setQuery($query);
$result = $db->loadResult();

Я хочу добиться ОБНОВЛЕНИЯ(увеличение на число) поля и получения результата(результат увеличения) одним запросом
Eтот запрос срабатывает в phpMyAdmin

Но Joomla вываливает ошибку:
1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT @new_count' at line 4 SQL=UPDATE `#__table_name` SET count = @new_count := id+5 WHERE `field` = 'my_field'; SELECT @new_count;

Joomla почемуто не делает подстановку префикса для таблицы  #__
Попробовал жёстко прописать префикс таблиц `prefix_table_name`, но Вываливает таже ошибка. Причём префикс магическим образом меняется на `#__table_name` О_о

Если сделать  $db->execute();  Получается таже беда Sad

Подскажите пожалуйста как правильно сделать такой запрос ??

UPD:
В моём случае Двумя запросами(1й изменение, 2й получение) делать нельзя,  так как после изменения может вклиниться повторное изменение от другого юзера, и тогда для первого прийдёт не верный результат Sad
« Последнее редактирование: 11.03.2017, 23:21:58 от avantyrist » Записан
Septdir
Практически профи
*******

Репутация: +106/-0
Online Online

Пол: Мужской
Сообщений: 2120



« Ответ #1 : 11.03.2017, 23:22:47 »

А причём тут префикс она и не должна. У вас в синтаксисе ошибка. А с префиксом все в порядке.  Если бы было не в порядке то писало бы не найдена таблица. 
Сам запрос разбирать не стал ибо с телефона.  Думаю дальше вы сами разбираетесь.
Записан
avantyrist
Давно я тут
****

Репутация: +3/-0
Offline Offline

Пол: Мужской
Сообщений: 230



« Ответ #2 : 11.03.2017, 23:31:29 »

Я понимаю что Joomla информирует об ошибке синтаксиса
НО я не понимаю какой О_о

Eтот запрос срабатывает в phpMyAdmin. Запрос  ИДЕНТИЧНЫЙ, только подставлен префикс таблицы
phpMyAdmin Показывает результат:

Отображает строки 0 - 0 ( 1 всего, запрос занял 0.0001 сек.)
@new_count
-------------
17


UPD:
$db->loadResult();  и аналогичные методы не позволяют выполнить   SELECT @new_count;

Подскажите пожалуйста как правильно сделать такой запрос ??

« Последнее редактирование: 11.03.2017, 23:54:11 от avantyrist » Записан
passer
Живу я здесь
******

Репутация: +73/-3
Offline Offline

Пол: Мужской
Сообщений: 951



« Ответ #3 : 11.03.2017, 23:53:31 »

Не великий спец, но помнится для нескольких запросов использовался
Код
$db->setQuery($sql);
$db->queryBatch();
 
Записан
avantyrist
Давно я тут
****

Репутация: +3/-0
Offline Offline

Пол: Мужской
Сообщений: 230



« Ответ #4 : 11.03.2017, 23:58:21 »

его нет в Joomla 3+  https://api.joomla.org/cms-3/classes/JDatabaseDriverMysqli.html#method_execute

и я не знаю что оно такое Sad
Записан
beliyadm
Профи
********

Репутация: +1590/-63
Offline Offline

Пол: Мужской
Сообщений: 8447


Севастополь == Россия


« Ответ #5 : 12.03.2017, 00:57:47 »

у вас ошибка на уровне переменной @new_count
сделайте проще
Код
SET count = count +1
Если конечно уверены в типе значений в поле count
Записан
dmitry_stas
Профи
********

Репутация: +935/-6
Online Online

Сообщений: 9958



« Ответ #6 : 12.03.2017, 01:07:39 »

В моём случае Двумя запросами(1й изменение, 2й получение) делать нельзя,  так как после изменения может вклиниться повторное изменение от другого юзера, и тогда для первого прийдёт не верный результат Sad
даже если бы Joomla понимала такую запись - у вас все равно 2 разных запроса. и между ними точно также мог бы вклинится другой процесс. а для решения этого давным давно придуманы транзакции и блокировки.
Записан
avantyrist
Давно я тут
****

Репутация: +3/-0
Offline Offline

Пол: Мужской
Сообщений: 230



« Ответ #7 : 12.03.2017, 01:23:01 »

Ух...
А разве пользовательская переменная живёт не во время текущего подключения к БД текущем юзером ??
Тоесть как я понимаю user_1 выполнил UPDATE, установил переменную @variable=1 и выполнил SELECT  тойже @variable переменной (Всё ето в одном подключении) и результат @variable доступен только user_1
  Под одним подключением к БД я понимаю $db->execute(); или схожие $db->load__();


или я не прав ? и получается чтото Вроде етого:

user_1
1) Выполняет php код
2) делает запрос к `table_1` чтото отработал и устанавливает @variable=11 (пользовательскую переменную)
3) возвращается к php коду(продолжается обработка после выборки из БД)
4) в етот момент user_2  выполнил тотже пункт 2) и 3)  но изменил значение @variable=99
5) теперь user_1 подключается опять к бд и делает SELECT @variable

Итог: у user_1 @variable  будет равен 99  или 11  ?
пункты 1,2,3,5  Выполняются в одном потоке(одним скриптом), одним Юзером
« Последнее редактирование: 12.03.2017, 01:31:06 от avantyrist » Записан
beliyadm
Профи
********

Репутация: +1590/-63
Offline Offline

Пол: Мужской
Сообщений: 8447


Севастополь == Россия


« Ответ #8 : 12.03.2017, 01:35:12 »

avantyrist - а это вам читать документацию по  MySQL lock table
И да - всегда хорошо иметь уникальные ключи, чтобы при блокировки таблицы не было дублей
Записан
Septdir
Практически профи
*******

Репутация: +106/-0
Online Online

Пол: Мужской
Сообщений: 2120



« Ответ #9 : 12.03.2017, 01:44:49 »

До барлся до компа.
Дабы не перелопачивать весь ваш запрос, скажу что dmitry_stas - это все равно два запроса. и можно вклиниться, но можно и без LOCK TABLES.
Поэтому если оставлять два запроса их просто надо попенять местами. Без всей логики сложно подсказать правильный вариант. Но попробую поиграть в угадайку.
Если мы не знаем значения count то логика такая:
1. Сначала делаем select получаем значение. делаем + 1
2. делаем запрос update
3. Отдаем юзеру значние из первого пунка
P.S как же сложно иногда предать логику словами.
Если мы занем count то логика такая:
По сути оптимальный вариант, изначально передавать занчение (ведь оно навреника выводиться перед отправкой)
2. делаем запрос update
3. Отдаем юзеру значние +1
Так запрос будет один.
С другой стороны, ничего страшного если пользователь получить не count+1 а точное значение из базы, тоже ничего страшного, думаю многие встречали нажал +1 а рейтинг изменился на +3 (т.к еще 2 человека нажали).
Еще вариант, если у вас AJAX то юзеру вообще ненужно выдеть что идет запрос. пусть у него сразу число увеличиваеться, тут главное сделать защиту от дураков чтобы по 3 подряд раза не нажимали, но ее все равно делать надо.

Так просто ради того чтобы было.

Записан
avantyrist
Давно я тут
****

Репутация: +3/-0
Offline Offline

Пол: Мужской
Сообщений: 230



« Ответ #10 : 12.03.2017, 01:47:05 »

beliyadm   я также ступорился с javaScript, тонкости ньюансы, Закалебался клянчить на форумах....   в Итоге меня климанолу и  я всё забросил и перелопатил Оочень много инфы по JS, в том числе книги...
Итог php забыт был напрочь Azn Joomla темболее...   в Голове Каша с Винигредом
Сейчас по новой всё востонавливаю по возможности, итог в Голове добавилось Оливье

Если сейчас также лезть  в SQL  можно идти в больничку....

По существу:
- Joomla поддерживает такой запрос на переменную ?  Как сделать выборку пользовательской переменной в Joomla  запросе ?
- По поводу жизни @variable как она себя ведёт ?  я склоняюсь к первоому моему Предположению.
   Изза того что в phpMyAdmin сначала сделать
      SET @var=9999;   -> выполнить
      SELECT @var;       -> выполнить
          результат будет NULL



Записан
robert
Профи
********

Репутация: +385/-15
Offline Offline

Пол: Мужской
Сообщений: 4217


« Ответ #11 : 12.03.2017, 01:54:08 »

http://php.net/manual/ru/ говорит:
Цитировать
Множественные запросы, или мультизапросы, должны запускаться функцией mysqli_multi_query().
...
Функции API mysqli_query() и mysqli_real_query() во время работы не устанавливают на сервере специальный флаг, необходимый для выполнения мультизапросов. Отдельная API функция для мультизапросов позволяет снизить вероятность случайных SQL инъекций. Злоумышленник может попытаться добавить в конец запроса выражения, вроде ; DROP DATABASE MySQL или ; SELECT SLEEP(999). Если ему это удастся, но не будет использоваться функция mysqli_multi_query, сервер не выполнит второе внедренное и опасное SQL выражение.
JDatabaseDriver не поддерживает mysqli_multi_query().
Записан
avantyrist
Давно я тут
****

Репутация: +3/-0
Offline Offline

Пол: Мужской
Сообщений: 230



« Ответ #12 : 12.03.2017, 01:59:02 »

robert спасибо
А я пойду пить чай...  нервы уже на пределе
Записан
Страниц: [1]   Вверх
  Добавить закладку  |  Печать  
 
Перейти в:  

Powered by SMF 1.1.21 | SMF © 2006, Simple Machines

Joomlaforum.ru is not affiliated with or endorsed by the Joomla! Project or Open Source Matters.
The Joomla! name and logo is used under a limited license granted by Open Source Matters
the trademark holder in the United States and other countries.

LiveInternet