Конструктор запросов
====================

Конструктор запросов Yii предоставляет объектно-ориентированный способ
написания SQL-запросов. Он позволяет разработчику использовать методы и свойства
класса для того, чтобы указать отдельные части SQL-запроса. Затем конструктор
собирает отдельные части в единый SQL-запрос, который может быть выполнен вызовом
методов DAO, как описано в «[Объекты доступа к данным (DAO)](/doc/guide/database.dao)».
Следующий код показывает типичное использование конструктора запросов для создания
SQL-запроса SELECT:

~~~
[php]
$user = Yii::app()->db->createCommand()
	->select('id, username, profile')
	->from('tbl_user u')
	->join('tbl_profile p', 'u.id=p.user_id')
	->where('id=:id', array(':id'=>$id))
	->queryRow();
~~~


Конструктор запросов лучше всего использовать в том случае, когда необходимо
собрать SQL-запрос, следуя некоторой условной логике приложения. Основными достоинствами
конструктора запросов являются:

* Возможность собрать сложный SQL-запрос программно.

* Автоматическое экранирование имён таблиц и полей для избежания конфликтов
с ключевыми словами SQL и специальными символами.

* Экранирование значений параметров и, где это возможно, использование привязки
параметров, помогающей избежать SQL-инъекций.

* Слой абстракции, упрощающий переход на другие СУБД.


Использовать конструктор запросов не обязательно. Если ваши запросы простые, легче
и быстрее использовать именно SQL.

> Note|Примечание: Конструктор запросов не может быть использован для
> изменения существующего запроса, заданного при помощи SQL.
> К примеру, не будет работать следующий код:
>
> ~~~
> [php]
> $command = Yii::app()->db->createCommand('SELECT * FROM tbl_user');
> // следующая строка НЕ добавит WHERE к SQL
> $command->where('id=:id', array(':id'=>$id));
> ~~~
>
> Не стоит использовать для одного запроса и SQL, и конструктор запросов.


Подготовка конструктора запросов
--------------------------------

Конструктор запросов реализован в классе [CDbCommand] — главном классе для
работы с базой данных, описанном в разделе «[Объекты доступа к данным (DAO)](/doc/guide/database.dao)».

Для того чтобы начать его использовать, необходимо создать новый экземпляр
[CDbCommand]:

~~~
[php]
$command = Yii::app()->db->createCommand();
~~~

Здесь мы используем `Yii::app()->db` для получения соединения с базой данных и
затем вызываем [CDbConnection::createCommand()] для создания экземпляра команды.

Следует отметить, что теперь мы не передаём методу `createCommand()` готовое SQL-выражение, как это делалось
[в случае с DAO](/doc/guide/database.dao).
Вместо этого мы соберём отдельные части запроса при помощи методов конструктора, которые описаны далее.


Запросы на получение данных
------------------------

Запросы на получение данных соответствуют SQL-запросам SELECT. В конструкторе
есть ряд методов для сборки отдельных частей SELECT запроса. Так как все
эти методы возвращают экземпляр [CDbCommand], мы можем использовать их
цепочкой, как показано в примере в начале этого раздела.

* [select()|CDbCommand::select() ]: часть запроса после SELECT.
* [selectDistinct()|CDbCommand::selectDistinct]: часть запроса после SELECT. Добавляет DISTINCT.
* [from()|CDbCommand::from() ]: часть запроса после FROM.
* [where()|CDbCommand::where() ]: часть запроса после WHERE.
* [join()|CDbCommand::join() ]: добавляет к запросу INNER JOIN.
* [leftJoin()|CDbCommand::leftJoin]: добавляет к запросу LEFT OUTER JOIN.
* [rightJoin()|CDbCommand::rightJoin]: добавляет к запросу RIGHT OUTER JOIN.
* [crossJoin()|CDbCommand::crossJoin]: добавляет к запросу CROSS JOIN.
* [naturalJoin()|CDbCommand::naturalJoin]: добавляет к запросу NATURAL JOIN.
* [group()|CDbCommand::group() ]: часть запроса после GROUP BY.
* [having()|CDbCommand::having() ]: часть запроса после HAVING.
* [order()|CDbCommand::order() ]: часть запроса после ORDER BY.
* [limit()|CDbCommand::limit() ]: часть запроса после LIMIT.
* [offset()|CDbCommand::offset() ]: часть запроса после OFFSET.
* [union()|CDbCommand::union() ]: часть запроса после UNION.


Рассмотрим использование перечисленных методов. Для простоты предположим, что
запросы делаются к MySQL. Для других СУБД способ экранирования названий таблиц, полей и значений,
используемый в примерах, может отличаться.


### select()

~~~
[php]
function select($columns='*')
~~~

Метод [select()|CDbCommand::select() ] задаёт часть запроса после `SELECT`. Параметр
`$columns` определяет выбираемые поля и может быть либо списком имён выбираемых
полей, разделённых запятой, либо массивом имён полей. Имена могут содержать
префиксы таблиц и псевдонимы полей. Метод автоматически экранирует имена, если
в них нет скобок (что означает использование выражения).

Несколько примеров:

~~~
[php]
// SELECT *
select()
// SELECT `id`, `username`
select('id, username')
// SELECT `tbl_user`.`id`, `username` AS `name`
select('tbl_user.id, username as name')
// SELECT `id`, `username`
select(array('id', 'username'))
// SELECT `id`, count(*) as num
select(array('id', 'count(*) as num'))
~~~


### selectDistinct()

~~~
[php]
function selectDistinct($columns)
~~~

Метод [selectDistinct()|CDbCommand::selectDistinct] делает то же, что и метод
[select()|CDbCommand::select() ], но добавляет к выражению `DISTINCT`. К примеру,
`selectDistinct('id, username')` сгенерирует следующий SQL:

~~~
SELECT DISTINCT `id`, `username`
~~~


### from()

~~~
[php]
function from($tables)
~~~

Метод [from()|CDbCommand::from() ] задаёт часть запроса после `FROM`. Параметр
`$tables` определяет, из каких таблиц производится выборка, и может быть либо
списком имён таблиц, разделённых запятыми, либо массивом имён таблиц. Имена могут
содержать префиксы схемы (такие, как `public.tbl_user`) и псевдонимы таблиц
(такие, как `tbl_user u`). Метод автоматически экранирует имена, если в них нет
скобок (что означает использование подзапроса или выражения).

Примеры:

~~~
[php]
// FROM `tbl_user`
from('tbl_user')
// FROM `tbl_user` `u`, `public`.`tbl_profile` `p`
from('tbl_user u, public.tbl_profile p')
// FROM `tbl_user`, `tbl_profile`
from(array('tbl_user', 'tbl_profile'))
// FROM `tbl_user`, (select * from tbl_profile) p
from(array('tbl_user', '(select * from tbl_profile) p'))
~~~


### where()

~~~
[php]
function where($conditions, $params=array())
~~~

Метод [where()|CDbCommand::where() ] задаёт часть запроса после `WHERE`. Параметр
`$conditions` определяет условия запроса, а `$params` — параметры, которые
подставляются в запрос. Значение параметра `$conditions` может быть как строкой
(например, `id=1`), так и массивом следующего вида:

~~~
[php]
array(operator, operand1, operand2, ...)
~~~

где `operator` может быть одним из следующих:

* `and`: операнды соединяются при помощи `AND`. К примеру, `array('and', 'id=1', 'id=2')`
сгенерирует `id=1 AND id=2`. Если операнд является массивом, то он будет преобразован
в строку с использованием описанных здесь правил. К примеру,
`array('and', 'type=1', array('or', 'id=1', 'id=2'))` сгенерирует
`type=1 AND (id=1 OR id=2)`. Данный метод ничего НЕ экранирует.

* `or`: то же, что и `and`, но для `OR`.

* `in`: первый операнд должнен быть столбцом или выражением, второй — массивом,
содержащим список значений, в которые должно входить значение поля или выражения.
К примеру, `array('in', 'id', array(1,2,3))` сгенерирует `id IN (1,2,3)`.
Метод экранирует имя столбца и значения в списке.

* `not in`: то же, что и `in`, но вместо `IN` используется `NOT IN`.

* `like`: первый операнд должен быть именем поля или выражением, второй — строкой
или массивом, содержащим список значений, на которые должно быть похоже значение
поля или выражения. К примеру, `array('like', 'name', '%tester%')` сгенерирует
`name LIKE '%tester%'`. Когда список значений является массивом, генерируется несколько
`LIKE`, соединённых при помощи `AND`. Например,
`array('like', 'name', array('%test%', '%sample%'))` сгенерирует
`name LIKE '%test%' AND name LIKE '%sample%'`. Метод экранирует имена полей и
значения в списке.

* `not like`: то же, что и `like`, но вместо `LIKE` генерируется `NOT LIKE`.

* `or like`: то же, что и `like` но для соединения `LIKE` используется `OR`.

* `or not like`: то же, что и `not like` но для соединения `NOT LIKE` используется `OR`.


Несколько примеров использования `where`:

~~~
[php]
// WHERE id=1 or id=2
where('id=1 or id=2')
// WHERE id=:id1 or id=:id2
where('id=:id1 or id=:id2', array(':id1'=>1, ':id2'=>2))
// WHERE id=1 OR id=2
where(array('or', 'id=1', 'id=2'))
// WHERE id=1 AND (type=2 OR type=3)
where(array('and', 'id=1', array('or', 'type=2', 'type=3')))
// WHERE `id` IN (1, 2)
where(array('in', 'id', array(1, 2))
// WHERE `id` NOT IN (1, 2)
where(array('not in', 'id', array(1,2)))
// WHERE `name` LIKE '%Qiang%'
where(array('like', 'name', '%Qiang%'))
// WHERE `name` LIKE '%Qiang' AND `name` LIKE '%Xue'
where(array('like', 'name', array('%Qiang', '%Xue')))
// WHERE `name` LIKE '%Qiang' OR `name` LIKE '%Xue'
where(array('or like', 'name', array('%Qiang', '%Xue')))
// WHERE `name` NOT LIKE '%Qiang%'
where(array('not like', 'name', '%Qiang%'))
// WHERE `name` NOT LIKE '%Qiang%' OR `name` NOT LIKE '%Xue%'
where(array('or not like', 'name', array('%Qiang%', '%Xue%')))
~~~

Стоит отметить, что в случае, когда оператор содержит `like`, необходимо явно
задавать спецсимволы (вроде `%` и `_`). Если паттерн вводится пользователем, то
необходимо использовать приведённый ниже код для экранирования спецсимволов и
предотвращения интерпретации их как спецсимволов:

~~~
[php]
$keyword=$_GET['q'];
// экранирует символы % и _
$keyword=strtr($keyword, array('%'=>'\%', '_'=>'\_'));
$command->where(array('like', 'title', '%'.$keyword.'%'));
~~~

### order()

~~~
[php]
function order($columns)
~~~

Метод [order()|CDbCommand::order() ] задаёт часть запроса после `ORDER BY`. Параметр
`$columns` определяет, по каким полям будет производиться сортировка. Поля могут
быть указаны как в виде строки, содержащей список полей и направлений
(`ASC` или `DESC`), разделённых запятыми, так и массив полей и направлений.
Имена полей могут содержать префиксы таблиц. Метод автоматически экранирует
имена полей, если они не содержат скобок (что означает использование выражения).

Несколько примеров:

~~~
[php]
// ORDER BY `name`, `id` DESC
order('name, id desc')
// ORDER BY `tbl_profile`.`name`, `id` DESC
order(array('tbl_profile.name', 'id desc'))
~~~


### limit() и offset()

~~~
[php]
function limit($limit, $offset=null)
function offset($offset)
~~~

Методы [limit()|CDbCommand::limit() ] и [offset()|CDbCommand::offset() ] задают
части запроса, следующие после `LIMIT` и `OFFSET`. Стоит отметить, что не все
СУБД поддерживают именно синтаксис `LIMIT` и `OFFSET`. Если он не поддерживается,
то конструктор запросов переписывает весь SQL-запрос для достижения схожего
эффекта.

Несколько примеров:

~~~
[php]
// LIMIT 10
limit(10)
// LIMIT 10 OFFSET 20
limit(10, 20)
// OFFSET 20
offset(20)
~~~


### join() и его варианты

~~~
[php]
function join($table, $conditions, $params=array())
function leftJoin($table, $conditions, $params=array())
function rightJoin($table, $conditions, $params=array())
function crossJoin($table)
function naturalJoin($table)
~~~

Метод [join()|CDbCommand::join() ] и его варианты задают порядок и параметры
соединения таблиц с использованием `INNER JOIN`, `LEFT OUTER JOIN`,
`RIGHT OUTER JOIN`, `CROSS JOIN` и `NATURAL JOIN`. Параметр `$table` определяет
таблицу, с которой производится соединение. Имя таблицы может содержать
префикс схемы или псевдоним. Метод экранирует имя таблицы, если оно не
содержит скобок, что означает использование подзапроса или выражения. Параметр
`$conditions` задаёт условие соединения. Синтаксис такой же, как и у
[where()|CDbCommand::where() ]. Через `$params` указываются параметры, подставляемые
в запрос.

Стоит отметить, что этот метод отличается от остальных тем, что каждый следующий
его вызов добавляет часть запроса к предыдущим.

Несколько примеров:

~~~
[php]
// JOIN `tbl_profile` ON user_id=id
join('tbl_profile', 'user_id=id')
// LEFT JOIN `pub`.`tbl_profile` `p` ON p.user_id=id AND type=1
leftJoin('pub.tbl_profile p', 'p.user_id=id AND type=:type', array(':type'=>1))
~~~


### group()

~~~
[php]
function group($columns)
~~~

Метод [group()|CDbCommand::group() ] задаёт часть запроса после `GROUP BY`.
Параметр `$columns` определяет поля, по которым будет осуществляться группировка,
и может быть либо строкой разделённых запятыми полей, либо массивом полей.
Имена полей могут содержать префиксы. Метод автоматически экранирует имена полей,
если они не содержат скобок (что означает использование выражений).

Несколько примеров:

~~~
[php]
// GROUP BY `name`, `id`
group('name, id')
// GROUP BY `tbl_profile`.`name`, `id`
group(array('tbl_profile.name', 'id'))
~~~


### having()

~~~
[php]
function having($conditions, $params=array())
~~~

Метод [having()|CDbCommand::having() ] задаёт часть запроса после `HAVING`. Используется
точно так же, как и [where()|CDbCommand::where() ].

Несколько примеров:

~~~
[php]
// HAVING id=1 or id=2
having('id=1 or id=2')
// HAVING id=1 OR id=2
having(array('or', 'id=1', 'id=2'))
~~~


### union()

~~~
[php]
function union($sql)
~~~

Метод [union()|CDbCommand::union() ] задаёт часть запроса после `UNION`. Он добавляет
`$sql` к сгенерированному запросу, используя `UNION`. Несколько вызовов `union()`
добавят несколько частей запроса.

Несколько примеров:

~~~
[php]
// UNION (select * from tbl_profile)
union('select * from tbl_profile')
~~~


### Выполнение запросов

После вызова приведённых выше методов для построения запроса, выполнить его можно,
используя методы DAO, как описано в разделе «[Объекты доступа к данным (DAO)](/doc/guide/database.dao)».
Например, мы можем использовать метод [CDbCommand::queryRow()] для получения строки или [CDbCommand::queryAll()]
для получения набора строк.

Пример:

~~~
[php]
$users = Yii::app()->db->createCommand()
	->select('*')
	->from('tbl_user')
	->queryAll();
~~~


### Получение SQL

Кроме выполнения запросов, которые мы создали при помощи конструктора, можно
также получить их SQL. Сделать это можно при помощи [CDbCommand::getText()].

~~~
[php]
$sql = Yii::app()->db->createCommand()
	->select('*')
	->from('tbl_user')
	->text;
~~~

Если у запроса есть параметры, получить их можно при помощи свойства
[CDbCommand::params].


### Альтернативный синтаксис построения запросов

Иногда использование цепочек вызовов может быть неоптимальным решением. Конструктор
запросов Yii позволяет создать запрос путём задания полей объекта. Для каждого
метода конструктора запросов есть соответствующее поле с таким же именем.
Присвоение значения полю эквивалентно вызову соответствующего метода. К примеру,
приведённые ниже строки эквивалентны, если `$command` — объект [CDbCommand]:

~~~
[php]
$command->select(array('id', 'username'));
$command->select = array('id', 'username');
~~~

Более того, метод [CDbConnection::createCommand()] может принимать массив в
качестве аргумента. Пары имя-значение из массива будут использованы для инициализации
полей созданного экземпляра [CDbCommand]. Таким образом, для построения запроса можно
использовать следующий код:

~~~
[php]
$row = Yii::app()->db->createCommand(array(
	'select' => array('id', 'username'),
	'from' => 'tbl_user',
	'where' => 'id=:id',
	'params' => array(':id'=>1),
))->queryRow();
~~~


### Построение нескольких запросов

Для построения нескольких запросов экземпляр [CDbCommand] может быть
использован несколько раз. Перед тем как построить новый запрос, необходимо
вызвать метод [CDbCommand::reset()] для очистки предыдушего запроса. Пример:

~~~
[php]
$command = Yii::app()->db->createCommand();
$users = $command->select('*')->from('tbl_users')->queryAll();
$command->reset();  // очищаем предыдущий запрос
$posts = $command->select('*')->from('tbl_posts')->queryAll();
~~~


Построение запросов для изменения данных
----------------------------------------

К запросам для изменения данных относятся SQL-запросы для вставки, обновления и
удаления данных из базы. В конструкторе запросов есть соответствующие методы
`insert`, `update` и `delete`. В отличие от запросов получения данных, описанных
выше, данные методы строят полный SQL-запрос и тут же выполняют его.

* [insert()|CDbCommand::insert]: вставляет строку в таблицу;
* [update()|CDbCommand::update]: обновляет данные в таблице;
* [delete()|CDbCommand::delete]: удаляет данные из таблицы.


### insert()

~~~
[php]
function insert($table, $columns)
~~~

Метод [insert()|CDbCommand::insert] строит и выполняет SQL-запрос `INSERT`. Параметр
`$table` указывает, в какую таблицу производится вставка, а `$columns` является
массивом пар имя-значение полей для вставки. Метод экранирует имя таблицы и использует
параметры для вставляемых значений.

Пример:

~~~
[php]
// строим и выполняем следующий SQL:
// INSERT INTO `tbl_user` (`name`, `email`) VALUES (:name, :email)
$command->insert('tbl_user', array(
	'name'=>'Tester',
	'email'=>'tester@example.com',
));
~~~


### update()

~~~
[php]
function update($table, $columns, $conditions='', $params=array())
~~~

Метод [update()|CDbCommand::update] строит и выполняет SQL-запрос `UPDATE`. Параметр
`$table` указывает обновляемую таблицу; `$columns` является массивом пар имя-значение,
задающим значения обновляемых полей; `$conditions` и `$params` эквивалентны аналогичным
параметрам в [where()|CDbCommand::where() ] и определяют часть запроса `UPDATE` после
`WHERE`. Метод экранирует имя таблицы и использует параметры для обновляемых значений.

Пример:

~~~
[php]
// строим и выполняем следующий SQL:
// UPDATE `tbl_user` SET `name`=:name WHERE id=:id
$command->update('tbl_user', array(
	'name'=>'Tester',
), 'id=:id', array(':id'=>1));
~~~


### delete

~~~
[php]
function delete($table, $conditions='', $params=array())
~~~

Метод [delete()|CDbCommand::delete] строит и выполняет SQL-запрос `DELETE`. Параметр
`$table` указывает таблицу, из которой удаляются записи; `$conditions` и `$params`
эквивалентны аналогичным параметрам в [where()|CDbCommand::where() ], которые определяют
часть запроса `DELETE` после `WHERE`. Метод экранирует имя таблицы.

Пример:

~~~
[php]
// строим и выполняем следующий SQL:
// DELETE FROM `tbl_user` WHERE id=:id
$command->delete('tbl_user', 'id=:id', array(':id'=>1));
~~~

Построение запросов изменения схемы
-----------------------------------

Кроме обычных запросов для получения данных и работы с ними, конструктор
может собирать и выполнять SQL-запросы для изменения схемы базы данных.
Поддерживаются следующие запросы:

* [createTable()|CDbCommand::createTable]: создание таблицы;
* [renameTable()|CDbCommand::renameTable]: переименование таблицы;
* [dropTable()|CDbCommand::dropTable]: удаление таблицы;
* [truncateTable()|CDbCommand::truncateTable]: очистка таблицы;
* [addColumn()|CDbCommand::addColumn]: добавление нового поля в таблицу;
* [renameColumn()|CDbCommand::renameColumn]: переименование поля таблицы;
* [alterColumn()|CDbCommand::alterColumn]: изменение поля таблицы;
* [dropColumn()|CDbCommand::dropColumn]: удаление поля таблицы;
* [createIndex()|CDbCommand::createIndex]: создание индекса;
* [dropIndex()|CDbCommand::dropIndex]: удаление индекса.

> Info|Информация: Несмотря на то что в разных СУБД запросы для измения схемы
различаются, конструктор запросов предоставляет единый интерфейс для их создания.
Это упрощает задачу мигрирования с одной СУБД на другую.


### Абстрактные типы данных

Конструктор запросов вводит ряд абстрактных типов данных, которые можно
использовать для описания полей таблицы. В отличие от реальных типов данных,
которые отличаются в разных СУБД, абстрактные типы не зависят от СУБД.
При использовании их для описания типов полей конструктор запросов конвертирует
абстрактные типы в соответствующие им реальные.

Конструктор запросов поддерживает следующие абстрактные типы:

* `pk`: обычный первичный ключ. Для MySQL конвертируется в `int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY`;
* `string`: строка. Для MySQL конвертируется в `varchar(255)`;
* `text`: текстовый тип (длинная строка). Для MySQL конвертируется в `text`;
* `integer`: целое. Для MySQL конвертируется в `int(11)`;
* `float`: число с плавающей точкой. Для MySQL конвертируется в `float`;
* `decimal`: дясятичное число. Для MySQL конвертируется в `decimal`;
* `datetime`: дата и время. Для MySQL конвертируется в `datetime`;
* `timestamp`: метка времени. Для MySQL конвертируется в `timestamp`;
* `time`: время. Для MySQL конвертируется в `time`;
* `date`: дата. Для MySQL конвертируется в `date`;
* `binary`: бинарный. Для MySQL конвертируется в `blob`;
* `boolean`: булевый. Для MySQL конвертируется в `tinyint(1)`;
* `money`: деньги/валюта. Для MySQL конвертируется в `decimal(19,4)`. Доступен с версии 1.1.8.


###createTable()

~~~
[php]
function createTable($table, $columns, $options=null)
~~~

Метод [createTable()|CDbCommand::createTable] строит и выполняет SQL-запрос для
создания таблицы. Параметр `$table` задаёт имя создаваемой таблицы. Параметр
`$columns` определяет поля новой таблицы. Они должны быть указаны в виде пар
имя-определение (т.е. `'username'=>'string'`). Параметр `$options` задаёт
дополнительный фрагмент SQL, который будет добавлен к генерируемому SQL.
Конструктор запроса экранирует имя таблицы и имена полей.

Для указания определения поля можно использовать один из абстрактных типов данных, описанных выше.
Конструктор конвертирует абстрактный тип данных в соответствующий реальный тип данных в соответствии с используемой СУБД.
Например, `string` в случае MySQL преобразуется в `varchar(255)`.

Определение поля также может содержать неабстрактный тип данных и спецификаций.
Они будут подставлены в результирующий SQL-запрос без каких-либо изменений. К примеру,
`point` не является абстрактным типом данных, и при использовании в определении
поля он будет включён в итоговый SQL без изменений. `string NOT NULL` будет
конвертирован в `varchar(255) NOT NULL` (т.е. конвертируются только абстрактный
тип `string`).

Пример создания таблицы:

~~~
[php]
// CREATE TABLE `tbl_user` (
//     `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
//     `username` varchar(255) NOT NULL,
//     `location` point
// ) ENGINE=InnoDB
createTable('tbl_user', array(
	'id' => 'pk',
	'username' => 'string NOT NULL',
	'location' => 'point',
), 'ENGINE=InnoDB')
~~~


###renameTable()

~~~
[php]
function renameTable($table, $newName)
~~~

Метод [renameTable()|CDbCommand::renameTable] строит и выполняет SQL-запрос для
переименования таблицы. Параметр `$table` задаёт имя изменяемой таблицы.
Параметр `$newName` определяет новое имя таблицы. Конструктор запроса
экранирует имена таблицы.

Пример переименования таблицы:

~~~
[php]
// RENAME TABLE `tbl_users` TO `tbl_user`
renameTable('tbl_users', 'tbl_user')
~~~


###dropTable()

~~~
[php]
function dropTable($table)
~~~

Метод [dropTable()|CDbCommand::dropTable] строит и выполняет SQL-запрос для удаления
таблицы. Параметр `$table` определяет имя удаляемой таблицы. Конструктор запроса
экранирует имя таблицы.

Пример удаления таблицы:

~~~
[php]
// DROP TABLE `tbl_user`
dropTable('tbl_user')
~~~

###truncateTable()

~~~
[php]
function truncateTable($table)
~~~

Метод [truncateTable()|CDbCommand::truncateTable] строит и выполняет SQL-запрос для
очистки всех данных таблицы. Параметр `$table` определяет имя очищаемой таблицы.
Конструктор запроса экранирует имя таблицы.

Пример очистки таблицы:

~~~
[php]
// TRUNCATE TABLE `tbl_user`
truncateTable('tbl_user')
~~~


###addColumn()

~~~
[php]
function addColumn($table, $column, $type)
~~~

Метод [addColumn()|CDbCommand::addColumn] строит и выполняет SQL-запрос для
добавления нового поля таблицы. Параметр `$table` задаёт имя таблицы, к которой
будет добавлено новое поле. Параметр `$column` — имя нового поля. `$type`
задаёт тип поля. Определение поля может содержать абстрактный тип данных,
как уже было описано в подразделе «createTable». Конструктор запроса
экранирует имя таблицы и имя поля.

Пример добавления поля:

~~~
[php]
// ALTER TABLE `tbl_user` ADD `email` varchar(255) NOT NULL
addColumn('tbl_user', 'email', 'string NOT NULL')
~~~


###dropColumn()

~~~
[php]
function dropColumn($table, $column)
~~~

Метод [dropColumn()|CDbCommand::dropColumn] строит и выполняет SQL-запрос для
удаления поля таблицы. Параметр `$table` задаёт имя таблицы, из которой удаляется
поле. Параметр `$column` определяет имя удаляемого поля. Конструктор запроса
экранирует имя таблицы и имя поля.

Пример удаления поля таблицы:

~~~
[php]
// ALTER TABLE `tbl_user` DROP COLUMN `location`
dropColumn('tbl_user', 'location')
~~~


###renameColumn()

~~~
[php]
function renameColumn($table, $name, $newName)
~~~

Метод [renameColumn()|CDbCommand::renameColumn] строит и выполняет SQL-запрос для
переименования поля таблицы. Параметр `$table` задаёт имя таблицы, поле которой
будет переименовано. Параметр `$name` определяет имя изменяемого поля.
`$newName` задаёт новое имя поля. Конструктор запроса экранирует имя таблицы и имена полей.

Пример переименования поля таблицы:

~~~
[php]
// ALTER TABLE `tbl_users` CHANGE `name` `username` varchar(255) NOT NULL
renameColumn('tbl_user', 'name', 'username')
~~~


###alterColumn()

~~~
[php]
function alterColumn($table, $column, $type)
~~~

Метод [alterColumn()|CDbCommand::alterColumn] строит и выполняет SQL-запрос для
изменения поля таблицы. Параметр `$table` задаёт имя таблицы, поле которой
будет изменено. Параметр `$column` определяет имя изменяемого поля. `$type`
задаёт новое определение поля, которое может содержать абстрактный тип данных,
как было описано в подразделе «createTable». Конструктор запросов экранирует имя
таблицы и имя поля.

Пример изменения поля таблицы:

~~~
[php]
// ALTER TABLE `tbl_user` CHANGE `username` `username` varchar(255) NOT NULL
alterColumn('tbl_user', 'username', 'string NOT NULL')
~~~




###addForeignKey()

~~~
[php]
function addForeignKey($name, $table, $columns,
	$refTable, $refColumns, $delete=null, $update=null)
~~~

Метод [addForeignKey()|CDbCommand::addForeignKey] строит и выполняет SQL-запрос для
добавления внешнего ключа в таблицу. Параметр `$name` задаёт имя внешнего ключа.
Параметры `$table` и `$columns` определяют имя таблицы и имя поля внешнего
ключа. Если указаны несколько полей, то они должны быть разделены запятыми.
Параметры `$refTable` и `$refColumns` определяют имя таблицы и имя поля, на которое
ссылается внешний ключ. Параметры `$delete` и `$update` задают SQL-опции
`ON DELETE` и `ON UPDATE` соответственно. Большинство СУБД поддерживают
следующие опции: `RESTRICT`, `CASCADE`, `NO ACTION`, `SET DEFAULT` и `SET NULL`.
Конструктор запросов экранирует имя таблицы, имя индекса и имена полей.

Пример добавления внешнего ключа:

~~~
[php]
// ALTER TABLE `tbl_profile` ADD CONSTRAINT `fk_profile_user_id`
// FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`)
// ON DELETE CASCADE ON UPDATE CASCADE
addForeignKey('fk_profile_user_id', 'tbl_profile', 'user_id',
	'tbl_user', 'id', 'CASCADE', 'CASCADE')
~~~


###dropForeignKey()

~~~
[php]
function dropForeignKey($name, $table)
~~~

Метод [dropForeignKey()|CDbCommand::dropForeignKey] строит и выполняет SQL-запрос
для удаления внешнего ключа. Параметр `$name` задаёт имя внешнего ключа,
который требуется удалить. Параметр `$table` — имя таблицы, из которой
удаляется ключ. Конструктор запроса экранирует имя таблицы и имя ключа.

Пример удаления внешнего ключа:

~~~
[php]
// ALTER TABLE `tbl_profile` DROP FOREIGN KEY `fk_profile_user_id`
dropForeignKey('fk_profile_user_id', 'tbl_profile')
~~~


###createIndex()

~~~
[php]
function createIndex($name, $table, $column, $unique=false)
~~~

Метод [createIndex()|CDbCommand::createIndex] строит и выполняет SQL-запрос
для создания индекса. Параметр `$name` задаёт имя индекса, который будет создан.
Параметр `$table` — имя таблицы, в которой создаётся индекс. Параметр `$column`
— имя индексируемого поля. Параметр `$unique` определяет, будет ли
индекс уникальным. Если индекс состоит из нескольких полей, то они разделяются
запятыми. Конструктор запросов экранирует имя таблицы, имя индекса и имена полей.

Пример создания индекса:

~~~
[php]
// CREATE INDEX `idx_username` ON `tbl_user` (`username`)
createIndex('idx_username', 'tbl_user', 'username')
~~~


###dropIndex()

~~~
[php]
function dropIndex($name, $table)
~~~

Метод [dropIndex()|CDbCommand::dropIndex] строит и выполняет SQL-запрос для
удаления индекса. Параметр `$name` задаёт имя удаляемого индекса.
Параметр `$table` — имя таблицы, из которой удаляется индекс. Конструктор
запроса экранирует имя таблицы и имя индекса.

Пример удаления индекса:

~~~
[php]
// DROP INDEX `idx_username` ON `tbl_user`
dropIndex('idx_username', 'tbl_user')
~~~