Fi1osof 02 апреля 2016 3 2
Обновляю сторонний магазин до последней версии, и решил сразу же перенести цены из таблицы данных товаров непосредственно в таблицу документов (в новой версии движка мы отказались от 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 в данном случае просто не пытается ничего экранировать и тогда мы на выходе получаем нормальный запрос с названием колонки.
2 комментария
b
bezumkin 06 апреля 2016г в 11:12 #
Спасибо, пригодилось!
Fi1osof1
Fi1osof 06 апреля 2016г в 13:24 #
Всегда пожалуйста!
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.