Обновляю сторонний магазин до последней версии, и решил сразу же перенести цены из таблицы данных товаров непосредственно в таблицу документов (в новой версии движка мы отказались от CRC). В целом SQL-запрос не сложный:
UPDATE `modx_site_content` JOIN `modx_shopmodx_products` `Product` ON `modx_site_content`.`id` = `Product`.`resource_id` SET `price` = Product.sm_price
На xPDO это получается примерно вот так:
$q = $modx->newQuery('modResource'); $q->command('update'); $q->innerJoin('ShopmodxProduct', "Product"); $q->set(array( "price" => "Product.sm_price", )); $s = $q->prepare(); print $q->toSQL(); // $s->execute();
Но если выполнить такой код, то мы получим вот такой запрос:
UPDATE `modx_site_content` JOIN `modx_shopmodx_products` `Product` ON `modx_site_content`.`id` = `Product`.`resource_id` SET `price` = 0
Почему так получается? Потому что xPDO рассчитан на обновление только текущей таблицы и ждет на вход только четкие значения, и эти значения он пытается привести к конечному виду в зависимости от типа данных. Для поля price тип данных — int, вот он и пытается строку «Product.sm_price» привести к интовому с логичным результатом — 0. Причем даже если мы заставим его понять, что это строка, в лучшем случае мы получим результат SET `price` = 'Product.sm_price', то есть он попытается присвоить не значение колонки sm_price, а просто строковое значение, которое мускул все равно приведет к нулю.
Не буду сильно лезть в дебри, а сразу решение приведу:
$q = $modx->newQuery('modResource'); $q->command('update'); $q->innerJoin('ShopmodxProduct', "Product"); $q->query['set']["price"] = array( "value" => "Product.sm_price", "type" => false, ); $s = $q->prepare(); print $q->toSQL(); // $s->execute();
Здесь мы сразу в объект запроса подставляем set-поля с указанием типа данных, точнее указывая нулевой тип. xPDO в данном случае просто не пытается ничего экранировать и тогда мы на выходе получаем нормальный запрос с названием колонки.
Спасибо, пригодилось!
Всегда пожалуйста!