INSERT в запросе UPDATE используя конструктор Joomla

  • 11 Ответов
  • 261 Просмотров

0 Пользователей и 1 Гость просматривают эту тему.

*

Оффлайн voron121

  • ****
  • 222
  • [+]1 / [-]0
  • Метод тыка и мата помогает в кодинге
    • Просмотр профиля
Доброго времени суток уважаемые форумчане. Хотел спросить, возможно ли выполняя запрос на обновление записей в БД сделать под запрос со вставкой данных в другую таблицу ?
Имеется вот такой код, он работает в цикле. Проходит по очереди все записи и списывает с учеток средства (автоматическое списание средств абонентов согласно тарифу.)

Код: (php) [Выделить]
       for($i = 0; $i < count($list); $i++) {
            $db = JFactory::getDbo();
            $query = $db->getQuery(true);
            $fields = array(
                $db->quoteName('balance_tv'). ' = ' . $db->quoteName('balance_tv').'-'.$db->quote($list[$i][2]),
            );
            $conditions = array(
                $db->quoteName('tarif_tv'). '='. $db->quote($list[$i][0]),
                $db->quoteName('status_tv'). '= 1 '
            );
            $query->update($db->quoteName('#__clients'))->set($fields)->where($conditions);
            $db->setQuery($query);
            $result = $db->execute();
        }

И в этом запросе мне нужно сделать INSERT в другую таблицу (таблица с историей изменения баланса). Если такое возможно - напишите плз где что почитать или ткните как сделать. Скрипт обрабатывает относительно много записей и что то городить лапшичное боюсь . По сути мне нужно вставить в таблицу #__log данные с ид пользователя у которого списали средства и сумму списания

*

Оффлайн zomby6888

В одном запросе у вас не получится делать вставки и обновления. По уму вам нужно использовать транзакции, batch insert и update. Тогда запроса будет всего два. Вы в вашем коде прогоняете по одному запросу за каждую итерацию цикла. Странно что у вас сервер не лег еще, если как вы говорите записей у вас много.
« Последнее редактирование: 14.11.2016, 16:23:50 от zomby6888 »
интернет-блог: http://websiteprog.ru

*

Оффлайн voron121

  • ****
  • 222
  • [+]1 / [-]0
  • Метод тыка и мата помогает в кодинге
    • Просмотр профиля
В одном запросе у вас не получится делать вставки и обновления. По уму вам нужно использовать транзакции, batch insert и update. Тогда запроса будет всего два. Вы в вашем коде прогоняете по одному запросу за каждую итерацию цикла. Странно что у вас сервер не лег еще, если как вы говорите записей у вас много.

За batch - спс, сейчас Google что это и с чем едят (ранее не сталкивался, не было потребности).

*

Оффлайн SmokerMan

Цитировать
INSERT в запросе UPDATE
называется REPLACE :)
но при этом надо следить что бы те данные которые записываются были идентичны тем что уже есть, иначе сотрутся не заполненные поля

*

Оффлайн voron121

  • ****
  • 222
  • [+]1 / [-]0
  • Метод тыка и мата помогает в кодинге
    • Просмотр профиля
называется REPLACE :)
но при этом надо следить что бы те данные которые записываются были идентичны тем что уже есть, иначе сотрутся не заполненные поля

суть в том что я делаю UPDATE в одной таблице а INSERT нужен к совсем другой. Тут REPLACE не подойдет явно ))

*

Оффлайн voron121

  • ****
  • 222
  • [+]1 / [-]0
  • Метод тыка и мата помогает в кодинге
    • Просмотр профиля
Господа, хотел бы у вас спросить : на счет bath, как советовал zomby6888, начал гуглить и читать  вещь интересная, но в связи с этим появилась пара вопросов.

У меня скрипт, в котором цикл циклом погоняет, создан для того что бы выполнять его по расписанию и является отдельным файлом не в компоненте Joomla. В самом скрипте я подключил либы Joomla для доступа к ее инструментам. Однако мне потребовалось вывести логи Joomla (стандартный инструмент отладки Joomla) в этом файле что бы посмотреть что там вообще происходит по времени и памяти в момент выполнения моего мега *** кода.

Подскажите как вывести консоль отладки Joomla в стороннем файле ?

И второй вопрос : у меня будет после работы скрипта происходить запись в отдельную таблицу (грубо говоря логирования). Логировать через фаил я не решился т.к записей предположительно будет много (исходя из предположительного количества абонентов 5 к то за год будет минимум 60 к записей  - 12 записей по 1 в месяц для каждого абонента ). В связи с этим [ВНЕЗАПНО!:)] я стал задумываться о том что же это будет : дохерища записей в таблице с логами.
По этому хотел у вас спросить : что можно предпринять что бы упростить работу для сайта в плане работы с логами ? Не ляжет ли сам сайт через год - 2 из-за большого количества записей в таблице с логами ? (предполагается отдельный компонент для просмотра логов, что бы было удобнее)

В общем как то так. Подскажите, направьте на путь истинный )

*

Оффлайн dmitry_stas

60К записей в год это много? то вы еще журнала nginx не видели :) 60К в год это пыль... log rotate поставите в крайнем случае
Тут дарят бакс просто за регистрацию! Успей получить!
Все советы на форуме раздаю бесплатно, то есть даром. Индивидуально бесплатно консультирую только по вопросам стоимости индивидуальных консультаций

*

Оффлайн robert

Подскажите как вывести консоль отладки Joomla в стороннем файле ?
Посмотрите PlgSystemDebug().
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Оффлайн voron121

  • ****
  • 222
  • [+]1 / [-]0
  • Метод тыка и мата помогает в кодинге
    • Просмотр профиля
60К записей в год это много? то вы еще журнала nginx не видели :) 60К в год это пыль... log rotate поставите в крайнем случае

ну тогда я спокоен ))

*

Оффлайн voron121

  • ****
  • 222
  • [+]1 / [-]0
  • Метод тыка и мата помогает в кодинге
    • Просмотр профиля
Посмотрите PlgSystemDebug().

Гляну, спасибо )

*

Оффлайн voron121

  • ****
  • 222
  • [+]1 / [-]0
  • Метод тыка и мата помогает в кодинге
    • Просмотр профиля
В одном запросе у вас не получится делать вставки и обновления. По уму вам нужно использовать транзакции, batch insert и update. Тогда запроса будет всего два. Вы в вашем коде прогоняете по одному запросу за каждую итерацию цикла. Странно что у вас сервер не лег еще, если как вы говорите записей у вас много.

Уважаемый zomby6888 , прошу немного объяснить по поводу batch . На сколько я понимаю транзакции позволяют делать несколько однотипных запросов в БД при этом снимая нагрузку с сервера. Я нашел метод

$db->transactionStart();  и  $db->queryBatch(); в стандартных инструментах работы Joomla с БД однако у меня возникло пара вопросов.

Получается что я должен в цикле создать серию запросов типа UPDATE `#__clients` SET `balance_domophone` = `balance_domophone`-'25' ;  и после передать всю строку с запросами в batch . Однако как мне это сделать  : в цикле присвоить переменной запросы и потом вне цикла ее отдать на исполнение или в цикле  и делать запрос ?

пример :

Код: (php) [Выделить]
try
{
    $db->transactionStart();
        // обновление баланса Домофон
       for($i = 0; $i < count($list2); $i++) {
            $fields = array(
                $db->quoteName('balance_domophone'). ' = ' . $db->quoteName('balance_domophone').'-'.$db->quote($list2[$i][2]),
            );

            $conditions = array(
                $db->quoteName('tarif_domophone'). '='. $db->quote($list2[$i][0]),
                $db->quoteName('status_domophon'). '= 1 '
            );
            $sql .=  $query->update($db->quoteName('#__clients'))->set($fields)->where($conditions).";";
        }


    $db->setQuery($sql);
    $db->queryBatch();

    $result = $db->execute();
    $db->transactionCommit();
}
catch (Exception $e)
{
    // catch any database errors.
    $db->transactionRollback();
    JErrorPage::render($e);
}

Так же не совсем ясна ситуация с методом $db->queryBatch(); - я так понял что его нет в Joomla 3 , тогда как быть  ?

Я прошу прощение за глупые вопросы но инфы в сети по данной теме практически нет и я не смогу найти ничего вразумительного

*

Оффлайн voron121

  • ****
  • 222
  • [+]1 / [-]0
  • Метод тыка и мата помогает в кодинге
    • Просмотр профиля
Доходит до меня видимо как до жирафа. Сосбвтенно почему не ложится сервер, как писали в топике, при выполнении запросов в БД в цикле . Суть такова что мне нужно выбрать н-ное количество тарифов из бд, и после в цикле списать с пользователей сумму с их баланса согласно тарифу. Тарифов не много и получается что я имею массив с тарифами, допустим 3 тарифа, и в цике делаю запрос на обновление баланса пользователей  с выборкой по тарифному плану. То есть в записе

Код: (php) [Выделить]
       for($i = 0; $i < count($list); $i++) {
            $db = JFactory::getDbo();
            $query = $db->getQuery(true);
            $fields = array(
                $db->quoteName('balance_tv'). ' = ' . $db->quoteName('balance_tv').'-'.$db->quote($list[$i][2]),
            );
            $conditions = array(
                $db->quoteName('tarif_tv'). '='. $db->quote($list[$i][0]),
                $db->quoteName('status_tv'). '= 1 '
            );
            $query->update($db->quoteName('#__clients'))->set($fields)->where($conditions);
            $db->setQuery($query);
            $result = $db->execute();
        }

получается на выходе всего лишь 3 запроса т.к будет лишь 3 тарифа и следовательно 3 итерации цикла.   Стыжусь каюсь, реально доходило долго .

Однако вопрос : мне нужно записать в таблицу с логами запись в которой будет указан id пользователя и сумма списания. При этом нужно знать сумму списания которая находится в пределах цикла for:

Код: (php) [Выделить]
for($i = 0; $i < count($list); $i++) {

И вот как это сделать я не могу понять . Вот здесь видимо и пригодились бы транзакции информации о которых не так уж много (