Fi1osof
18 июня 2016 г., 22:02

Удаление записей сразу из нескольких таблиц средствами xPDO

В блоге Tips & tricks

Сразу скажу, что без хака xPDO такого не умеет делать. Дело в том, что при перечислении нескольких таблиц в конструкции DELETE FROM надо явно указывать из каких именно перечисленных таблиц надо выполнить удаление. То есть вот классический запрос удаления записей из одной таблицы:
DELETE FROM table;
Такой запрос средствами xPDO строится запросто.
$q = $modx->newQuery('class_name'); $q->command('DELETE'); $q->prepare() ->execute();
А вот при перечислении таблиц SQL-конструкция выглядит так:
DELETE table1, table2 FROM table1, table2, table3
Так вот этого перечисления table1, table2 xPDO не умеет делать. Перечисление выполняется только в случае команд SELECT и UPDATE. А при DELETE ничего не подставляется.
В общем, после нескольких экспериментов я пришел вот к такому коду:
'; $table = $modx->getTableName("modTemplateVarResource"); $q = $this->modx->newQuery("modTemplateVarResource"); $q->setClassAlias(''); $q->innerJoin('modResource', 'Resource'); $q->query['command']= "DELETE {$table}"; $q->where(array( "tmplvarid" => 11, )); $s = $q->prepare(); $s->execute();
На выходе получается вот такой работающий SQL:
DELETE `modx_site_tmplvar_contentvalues` FROM `modx_site_tmplvar_contentvalues` JOIN `modx_site_content` `Resource` ON ``.`contentid` = `Resource`.`id` WHERE ( `modx_site_tmplvar_contentvalues`.`tmplvarid` = 11)
И вот здесь два момента:
1. Не получается использовать $q->command(«DELETE {$table}»); Дело в том, что xPDO переводит это в верхний регистр, а так как название таблицы формируется с наклонными кавычками (что мускулом воспринимается с учетом регистра), то мы получим сообщение об отсутствующей таблице.
DELETE `MODX_SITE_TMPLVAR_CONTENTVALUES` FROM `modx_site_tmplvar_contentvalues` JOIN `modx_site_content` `Resource` ON ``.`contentid` = `Resource`.`id` WHERE ( `modx_site_tmplvar_contentvalues`.`tmplvarid` = 11 ) Array ( [0] => 42S02 [1] => 1109 [2] => Unknown table 'MODX_SITE_TMPLVAR_CONTENTVALUES' in MULTI DELETE )
2. Нельзя забывать про сброс алиаса $q->setClassAlias(''), иначе у нас условия пойдут с несуществующим алиасом таблицы.
DELETE `modx_site_tmplvar_contentvalues` FROM `modx_site_tmplvar_contentvalues` JOIN `modx_site_content` `Resource` ON `modTemplateVarResource`.`contentid` = `Resource`.`id` WHERE ( `modx_site_tmplvar_contentvalues`.`tmplvarid` = 11 AND `modx_site_tmplvar_contentvalues`.`value` = '9999999999999999999' ) Array ( [0] => 42S22 [1] => 1054 [2] => Unknown column 'modTemplateVarResource.contentid' in 'on clause' )
P.S. зачем мне такое вообще нужно было? Мне надо было удалить ТВшки только определенных документов, а для этого или надо было все ID-шники сначала получать, затем в IN(...) скармливать (а я такое не люблю), или формировать конструкцию WHERE EXISTS или еще что-то в подобном виде.

Добавить комментарий