mirror of
https://github.com/yiisoft/yii.git
synced 2026-03-04 15:24:07 +01:00
921 lines
41 KiB
Plaintext
921 lines
41 KiB
Plaintext
Конструктор запросов
|
||
====================
|
||
|
||
Конструктор запросов 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')
|
||
~~~ |