Powered by Prisma CMS

Читайте все статьи на prisma-cms.com

Fi1osof
2 мая 2013 г., 20:39

Запросы на UPDATE, DELETE и т.п., а так же отладка чистых SQL-запросов, выполняемых через PDO

Я думаю, много уже кто выполнял SQL-запросы через $modx->newQuery(), ->prepare(), ->execute(); Но далеко не все знают, что таким образом можно выполнять не только SELECT-запросы, но и UPDATE и DELETE. Для этого существуют методы xPDOQuery::command() и xPDOQuery::set().
Метод xPDOQuery::command() по умолчанию устанавливает тип запроса SELECT, но как видите, может и другие типы устанавливать.
public function command($command= 'SELECT') { $command= strtoupper(trim($command)); if (preg_match('/(SELECT|UPDATE|DELETE)/', $command)) { $this->query['command']= $command; if (in_array($command, array('DELETE','UPDATE'))) $this->_alias= $this->xpdo->getTableName($this->_class); } return $this; }
Приведу небольшой пример запроса:
$c = $modx->newQuery('modResource'); $c->command('update'); $c->set(array( 'hidemenu' => 1 )); $c->where(array( 'parent' => 11, )); $c->prepare(); // print $c->toSQL(); $c->stmt->execute();
Конечный SQL-запрос этого скрипта:
UPDATE `modx_site_content` SET `hidemenu` = 1 WHERE `modx_site_content`.`parent` = 11
Как видите, у нас здесь и условия поиска, и установка новых значений есть. Само собой можно и более сложные запросы набросать.
Второй вопрос — отладка таких запросов. Ведь при выполнении таких запросов при ошибках на уровне базы данных вы просто ничего не увидите. Здесь требуются дополнительные движения.
В первую очередь надо учесть, что при выполнении метода $c->prepare() мы получаем объект PDOStatement (как результат выполнения метода xPDO::prepare())
/** * @see http://php.net/manual/en/function.pdo-prepare.php */ public function prepare($statement, $driver_options= array ()) { if (!$this->connect()) { return false; } return $this->pdo->prepare($statement, $driver_options= array ()); }
Соответственно и работать надо именно с этим объектом и на уровне его методов. (собственно, это и происходит, когда мы выполняем $c->stmt->execute(), $c->stmt->fetchAll() и т.п.). И для вывода ошибок нам и нужно работать с этим объектом. К примеру, чтобы получить информацию о возникших SQL-ошибках, можно выполнить print_r($c->stmt->errorInfo());
Добрый день! Подскажите, а как поменять название таблицы, в которой выполняешь UPDATE?
Вопрос как-то некорректно поставлен. Поменять таблицу, в которой изменения делаются? Или переименовать таблицу?
Если случай первый, то в строке $c = $modx->newQuery('modResource'); и задаётся таблица для изменения (все объекты xpdo привязаны к таблицам).
Если надо переименовать таблицу (зачем?!), то тут update не поможет.
Вы правы, случай первый. Извините за назойливость, я просто не силен в ООП. То есть, если мне нужно обновить value доп поля №11 в ресурсе №5 в таблице cts_site_tmplvar_contentvalues, то мой запрос будет такой(?):
Нужно получить (UPDATE `cts_site_tmplvar_contentvalues` SET `value` = 'gift' WHERE (`tmplvarid` = 11 AND `contentid` = 5) ) $c = $modx->newQuery('cts_site_tmplvar_contentvalues'); $c->command('update'); $c->set(array( 'value' => 'gift' )); $c->where(array( 'tmplvarid' => 11, 'contentid' => 5 )); $c->prepare(); // print $c->toSQL(); $c->stmt->execute();

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