Caution: The documentation you are viewing is
for an older version of Zend Framework.
You can find the documentation of the current version at:
https://docs.zendframework.com/
Zend_Db_Select - Zend_Db
Объект Zend_Db_Select представляет SQL-оператор SELECT
.
Класс имеет методы для добавления отдельных частей запроса. Вы
можете определять некоторые части запроса, используя методы PHP и
структуры данных, и класс формирует корректный синтаксис SQL.
После того, как построен запрос, можно выполнять его так же, как
если бы он был написан в виде строки.
В число достоинств Zend_Db_Select входит:
Объектно-ориентированные методы для "покусочного" построения SQL-запросов;
Не зависящая от типа БД абстракция некоторых частей SQL-запроса;
Автоматическое в большинстве случаев заключение в кавычки идентификаторов метаданных для поддержки идентификаторов, содержащих зарезервированные SQL слова и спецсимволы;
Заключение в кавычки идентификаторов и значений для снижения угрозы атак с использованием SQL-инъекций.
Использование Zend_Db_Select не обязательно. Для очень простых
запросов SELECT обычно проще указать SQL-запрос целиком в виде
строки и выполнить его, используя такие методы адаптера, как
query()
или fetchAll()
. Использование
Zend_Db_Select полезно, если нужно собрать запрос SELECT в процессе
или основываясь на условной логике.
Вы можете создавать экземпляр объекта Zend_Db_Select, используя
метод select()
объекта Zend_Db_Adapter_Abstract.
Example #1 Пример использования метода select() адаптера БД
Другой способ состоит в создании объекта Zend_Db_Select через конструктор, при этом в качестве аргумента указывается адаптер БД.
Example #2 Пример создания нового объекта Select
При построении запроса вы можете добавлять по одному его предложения. Предложение - это часть SQL-оператора, не представляющая собой законченный оператор; например, предложение WHERE. Для каждого предложения есть свой метод Zend_Db_Select.
Example #3 Пример использования методов для добавления предложений
Вы также можете использовать большинство методов объекта Zend_Db_Select в так называемом fluent interface. Fluent interface означает, что каждый метод возвращает ссылку на тот объект, в котором он был вызван, поэтому вы можете вызывать другой метод непосредственно за ним.
Example #4 Пример использования fluent interface
Этот пример демонстрирует применение fluent interface, но в любом случае вы можете использовать стандартный подход. Часто бывает необходимо использовать стандартный подход - например, когда нужно выполнить некоторую логику до добавления предложения в запрос.
Указывайте таблицу для запроса, используя метод
from()
. Вы можете задавать имя таблицы в виде
простой строки, Zend_Db_Select добавит идентификатор, заключив в
кавычки имя таблицы, поэтому вы можете использовать специальные
символы.
Example #5 Пример использования метода from()
Вы можете также задавать корреляционное (называемое также "псевдонимом") имя таблицы. В этом случае вместо простой строки используйте ассоциативный массив корреляционных имен и действительных имен таблиц. В других предложениях SQL-запроса используйте это корреляционное имя. Если в вашем запросе объединяется более одной таблицы, то Zend_Db_Select генерирует уникальные корреляционные имена, основанные на именах таблиц, для всех таблиц, для которых не были заданы корреляционные имена.
Example #6 Пример задания корреляционного имени таблицы
Некоторые СУРБД поддерживают спецификатор схемы для таблицы. Вы
можете задавать имя таблицы в виде
"имяСхемы.имяТаблицы
". Zend_Db_Select заключит в
кавычки все части по отдельности.
Example #7 Пример задания имени схемы
Во втором аргументе метода from()
вы можете
задавать столбцы для выборки из соответствующей таблицы. Если вы
не укажете столбцы для выборки, то по умолчанию будет подставлен
метасимвол "*
", означающий "все столбцы".
Вы можете перечислить столбцы в простом массиве строк или в ассоциативном массиве псевдонимов столбцов и их имен. Если в запросе нужен только один столбец, и к нему не нужен псевдоним, то можно передать строку с его именем вместо массива.
Если вы передали пустой массив в качестве аргумента для
столбцов, то ни один столбец из соответствующей таблицы не будет
включен в результат выборки. См.
пример
кода в разделе про метод join()
.
Вы можете указать имя столбца как
"корреляционноеИмя.имяСтолбца
". Zend_Db_Select
заключит в кавычки все части по отдельности. Если вы не укажете
корреляционное имя для столбца, то используется корреляционное
имя таблицы, указанной в текущем вызове метода
from()
.
Example #8 Пример указания столбцов
Столбцы в SQL-запросах иногда представляют собой выражения, а не просто столбцы из таблицы. Выражения не должны иметь корреляционные имена и заключаться в кавычки. Если строка, обозначающая столбец запроса, содержит скобки, то Zend_Db_Select распознает ее как выражение.
Вы можете также явно создавать объект типа Zend_Db_Expr для того, чтобы предотвратить ошибочное распознавание строки как имени столбца. Zend_Db_Expr - мини-класс, содержащий только строку. Zend_Db_Select распознает объекты типа Zend_Db_Expr и преобразует их обратно в строку, но без таких действий, как заключение в кавычки и добавление корелляционных имен.
Note: Использование Zend_Db_Expr не обязательно, если ваше выражение содержит скобки. Zend_Db_Select распознает выражение по скобкам и оперирует строкой как выражением, пропуская такие действия, как заключение в кавычки и добавление корреляционных имен.
Example #9 Пример указания столбцов, содержащих выражения
В примерах выше Zend_Db_Select не модифицирует строку для добавления корреляционных имен или заключения идентификаторов в кавычки. Если эти изменения необходимы для исключения неоднозначности, то вы должны произвести их в строке вручную.
Если имена столбцов являются ключевыми словами SQL или содержат
специальные символы, то следует использовать метод адаптера
quoteIdentifier()
и включать результат в строку.
Метод quoteIdentifier()
использует заключение в
кавычки для ограничения идентификатора, тем самым обозначается,
что это идентификатор таблицы или столбца, а не другая часть
синтаксиса SQL.
Ваш код будет более независимым от типа БД, если вы будете
использовать метод quoteIdentifier()
вместо
непосредственного добавления кавычек в строке, поскольку
некоторые БД используют нестандартные символы вместо кавычек.
Метод quoteIdentifier()
использует нужные символы, основываясь на типе
адаптера. quoteIdentifier()
также экранирует
символы кавычек в самом идентификаторе.
Example #10 Пример заключения в кавычки столбцов в выражении
Может потребоваться добавить столбцы в таблицу FROM или JOIN
после того, как были вызваны соответствующие методы. Метод
columns()
позволяет добавлять определенные столбцы
в любой момент до того, как будет выполнен запрос. Вы можете
передавать столбцы в виде строки, объекта
Zend_Db_Expr
или массива этих элементов. Второй
аргумент этого метода может быть опущен, это значит, что столбцы
должны быть добавлены в таблицу FROM, иначе должно
использоваться существующее корреляционное имя.
Example #11 Пример добавления столбцов через метод columns()
Многие полезные запросы используют JOIN
для
объединения строк из разных таблиц. Вы можете добавлять таблицы
в запрос, используя метод join()
объекта
Zend_Db_Select. Использование этого метода похоже на
использование from()
за тем исключением, что в
большинстве случаев вам нужно будет также указать условие
объединения.
Example #12 Пример использования метода join()
Второй аргумент метода join()
является строкой,
содержащей условие объединения. Это выражение объявляет условие,
при выполнении которого строки в одной таблице объединяются со
сроками в другой таблице. Вы можете использовать корреляционные
имена в этом выражении.
Note: К выражению, указанному вами как условие объединения, не применяется автоматическое заключение в кавычки. Если нужно заключить в кавычки имена столбцов, то используйте
quoteIdentifier()
при формировании строки условия объединения.
Третий аргумент метода join()
- массив имен
столбцов, как и в методе from()
. По умолчанию
используется "*
" вместо столбцов,
поддерживаются корреляционные имена, выражения и Zend_Db_Expr -
так же, как и в случае массива столбцов для метода
from()
.
Если из таблицы не нужно выбирать столбцы, то используйте пустой
массив вместо перечисления столбцов. Это работает и для метода
from()
, но обычно требуется извлечь часть столбцов
из основной таблицы в запросе, при этом может не требоваться
получение столбцов из присоединяемой таблицы.
Example #13 Пример извлечения без столбцов
Обратите внимание на пустой array()
в примере
выше вместо списка столбцов из присоединяемой таблицы.
SQL имеет несколько типов объединений. Ниже приведен список методов для поддержки различных типов объединений в Zend_Db_Select.
INNER JOIN, методы
join(table, join, [columns])
и joinInner(table, join, [columns])
.
Возможно, наиболее часто используемый тип объединения. Строки из каждой таблицы сравниваются с использованием условия сравнения. Результат включает в себя только те строки, которые удовлетворяют условию объединения. Результат может быть пустым, если ни одна строка не удовлетворяет этому условию.
Все СУРБД поддерживают этот тип объединения.
LEFT JOIN, метод joinLeft(table, condition, [columns])
.
В результат входят все строки из таблицы слева и все соответствующие строки из таблицы справа. Если нет соответствующих строк из таблицы справа, то соответствующие столбцы в результате заполняются NULL.
Все СУРБД поддерживают этот тип объединения.
RIGHT JOIN, метод joinRight(table, condition, [columns])
.
Правое внешнее объединение дополняет левое внешнее объединение. В результат входят все строки из таблицы справа и все соответствующие строки из таблицы слева. Если нет соответствующих строк из таблицы слева, то соответствующие столбцы в результате заполняются NULL.
Некоторые СУРБД не поддерживают этот тип объединения, но, как правило, любое правое объединение может быть заменено на левое посредством изменения порядка таблиц на обратный.
FULL JOIN, метод
joinFull(table, condition, [columns])
.
Полное внешнее объединение является как бы комбинацией левого и правого объединений. Все строки из обоих таблиц входят в результат, при этом объединяются друг с другом в одну строку результата, если соответствуют условию объединения, иначе объединяются с NULL вместо значений столбцов из другой таблицы.
Некоторые СУРБД не поддерживают этот тип объединения.
CROSS JOIN, метод
joinCross(table, [columns])
.
Перекрестное объединение является декартовым произведением. Каждая строка в первой таблице объединяется с со всеми строками во второй таблице. Таким образом, количество строк в результате будет равно произведению числа строк в обоих таблицах. Вы можете фильтровать результат, используя условие в предложении WHERE, в этом случае перекрестное объединение подобно старому синтаксису объединений в SQL-89.
Метод joinCross()
не имеет параметров для
определения условий объединения. Некоторые СУРБД не
поддерживают этот тип объединения.
NATURAL JOIN, метод
joinNatural(table, [columns])
.
Естественное объединение сравнивает столбцы, имеющие одинаковые имена в обоих таблицах. Проверка производится на равенство; проверка на неравенство не является естественным объединением. Данным API поддерживаются только внутренние естественные объединения, даже если SQL поддерживает внешние естественные объединения.
Метод joinNatural()
не имеет параметров для
определения условий объединения.
В дополнение к этим методам объединения вы можете упростить свои запросы, используя методы JoinUsing. Вместо предоставления полного условия объединения вы можете просто передавать имя столбца, по которому производится объединение, и Zend_Db_Select допишет условие объединения за вас.
Example #14 Пример использования метода joinUsing()
Каждый метод объединения из перечисленных выше имеет соответствующий ему метод JoinUsing.
joinUsing(table, join, [columns])
и
joinInnerUsing(table, join, [columns])
joinLeftUsing(table, join, [columns])
joinRightUsing(table, join, [columns])
joinFullUsing(table, join, [columns])
Вы можете задавать условия для ограничения строк в результате
выборки, используя метод where()
. Первым аргументом
этого метода является SQL-выражение, которое используется в
предложении WHERE
в данном запросе.
Example #15 Пример использования метода where()
Note: К выражениям для методов
where()
илиorWhere()
не применяется автоматическое заключение в кавычки. Если необходимо, чтобы имена столбцов были заключены в кавычки, то используйте методquoteIdentifier()
при формировании строки условия.
Второй аргумент метода where()
является
опциональным. Это значение подставляется в выражение.
Zend_Db_Select заключает это значение в кавычки и подставляет
вместо знака вопроса ("?
") в выражении.
Этот метод принимает только один параметр. Если в выражение подставляется несколько значений, то нужно сформировать строку вручную, вставляя переменные и заключая их в кавычки самостоятельно.
Example #16 Пример параметра в методе where()
Вы можете вызывать метод where()
несколько раз на
одном и том же объекте Zend_Db_Select. Результирующий запрос
объединяет в себе все термы с добавлением AND
между ними.
Example #17 Пример нескольких вызовов метода where()
Если вам нужно объединить термы с использованием
OR
, то используйте метод orWhere()
.
Этот метод используется так же, как и метод
where()
, за тем исключением, что определенный в
этом вызове терм добавляется вместе с OR
вместо
AND
.
Example #18 Пример использования метода orWhere()
Zend_Db_Select автоматически заключает в скобки все выражения,
которые вы добавляете через методы where()
или
orWhere()
. Это позволяет быть уверенным в том, что
приоритет булевых операторов не приведет к другому результату
вместо ожидаемого.
Example #19 Пример заключения булевых выражений в скобки
В примере выше результаты могут отличаться от тех, что
получаются без скобок, потому что AND
имеет больший
приоритет, чем OR
. Zend_Db_Select добавляет скобки,
Таким образом, результатом является то, что каждое выражение,
добавленное в успешных вызовах where()
более
связанно, чем AND
, объединяющее эти выражения.
В языке SQL выражение GROUP BY
позволяет ограничить
количество строк в результатах запроса до одной стоки на каждое
уникальное значение в столбцах, перечисленных в предложении
GROUP BY
.
В Zend_Db_Select вы можете задавать столбцы, используемые для
определения групп строк, через метод group()
.
Аргументом этого метода является столбец или массив столбцов для
подстановки в предложение GROUP BY
.
Example #20 Пример использования метода group()
Как и для массива столбцов в методе from()
, вы
можете использовать корреляционные имена в именах столбцов,
столбцы заключаются в кавычки в качестве идентификаторов, если
строка не содержит скобок или является объектом типа
Zend_Db_Expr.
В SQL предложение HAVING
применяет условие
ограничения к группам строк. Это подобно тому, как предложение
WHERE
применяет условие ограничения к строкам.
Но эти предложения не являются идентичными, поскольку условия
WHERE
применяются до группировки, в то время как
условия HAVING
применяется после группировки.
В Zend_Db_Select вы можете определять условия ограничения
групп через метод having()
. Его использование
аналогично использованию метода where()
. Первый
аргумент является строкой, содержащей SQL-выражение.
Опциональный второй аргумент - значение, которое используется
для подстановки вместо метки заполнения в SQL-выражении.
Выражения, переданные в нескольких вызовах метода
having()
, объединяются через булевый оператор
AND
или через булевый оператор
OR
, если вы используете метод
orHaving()
.
Example #21 Пример использования метода having()
Note: К выражениям, переданным через методы
having()
илиorHaving()
, не применяется автоматическое заключение в кавычки. Если у вас есть имена столбцов, которые требуется заключить в кавычки, то используйтеquoteIdentifier()
при формировании строки условия.
В SQL предложение ORDER BY
задает один или более
столбцов (или выражений), по которым сортируется результат
запроса. Если перечислено несколько столбцов, то вторичные
столбцы используются для принятия решения в ситуации "ничьи":
если первичные столбцы содержат идентичные значения, то порядок
сортировки определяется через вторичные столбцы. По умолчанию
сортировка производится от меньших значений к большим. Вы можете
также производить для данного столбца сортировку от больших
значений к меньшим, указав ключевое слово DESC
после этого столбца.
В Zend_Db_Select вы можете использовать метод
order()
для определения столбца или массива
столбцов, по которым производится сортировка. Каждый элемент
массива является строкой с именем столбца, опционально строка
может содержать ключевое слово ASC
или
DESC
после имени столбца и отделенное от него
пробелом.
Как и в случае методов from()
и
group()
, имена столбцов заключаются в кавычки в
качестве идентификаторов, если они не содержат скобки и не
являются объектами Zend_Db_Expr.
Example #22 Пример использования метода order()
Некоторые СУРБД расширяют язык SQL предложением, известным как
предложение LIMIT
. Это предложение ограничивает
количество строк в результате запроса до заданного вами
количества. Вы можете также задать количество пропускаемых до
начала вывода строк. Эта возможность облегчает выборку
подмножества строк результата - например, для постраничного
вывода результатов запроса.
В Zend_Db_Select вы можете использовать метод
limit()
для задания количества строк в выборке и
количества пропускаемых строк. Первым аргументом этого метода
является желаемое количество строк в результате запроса. Вторым
аргументом - количество пропускаемых строк
Example #23 Пример использования метода limit()
Note: Ситаксис
LIMIT
поддерживается не всеми СУРБД. Некоторые СУРБД используют другой синтаксис для поддержки аналогичной функциональности. Каждый класс Zend_Db_Adapter_Abstract включает в себя метод для генерации SQL, присущего данной СУРБД.
Используйте метод limitPage()
в качестве
альтернативного способа указания количества строк и смещения.
Этот метод позволяет ограничить набор возвращаемых результатов
подмножеством фиксированной длины, который является одним из
последовательности подмножеств, составляющих весь набор
результатов запроса.
Другими словами, вы указываете длину "страницы" результатов в
строках и порядковый номер страницы для извлечения. Номер
страницы является первым аргументом в методе
limitPage()
, а длина страницы - вторым. Оба
аргумента являются обязательными и не имеют значений по
умолчанию.
Метод distinct()
дает возможность добавлять
ключевое слово DISTINCT
в ваш запрос.
Example #25 Пример использования метода distinct()
Метод forUpdate()
дает возможность добавлять
модификатор FOR UPDATE
в ваш запрос.
Example #26 Пример использования метода forUpdate()
Этот раздел объясняет, как производить запрос, представленный объектом Zend_Db_Select.
Вы можете производить запрос, представленный объектом
Zend_Db_Select, посредством передачи его в качестве первого
аргумента методу query()
объекта
Zend_Db_Adapter_Abstract. Используйте объекты Zend_Db_Select
вместо строк запроса.
Метод query()
возвращает объект Zend_Db_Statement
или PDOStatement, в зависимости от типа адаптера.
Example #27 Пример использования метода query() адаптера БД
Вместо метода query()
объекта адаптера можно
использовать метод query()
объекта Zend_Db_Select.
Оба метода возвращают объект типа Zend_Db_Statement или
PDOStatement, в зависимости от типа адаптера.
Example #28 Пример использования метода query() объекта Select
Если нужно получить доступ к строковому представлению
SQL-запроса, соответствующего данному объекту Zend_Db_Select, то
используйте метод __toString()
.
Example #29 Пример использования метода __toString()
Этот раздел описывает другие методы класса Zend_Db_Select, которые
не были охвачены ранее: getPart()
и
reset()
.
Метод getPart()
возвращает представление
определенной части вашего запроса. Например, вы можете
использовать этот метод для получения строки выражения для
предложения WHERE
, массива столбцов, перечисленных
для получения выборки по ним, значений количества и смещения для
предложения LIMIT
.
Возвращаемое значение не является строкой, содержащей фрагмент запроса SQL. Возвращаемое значение является внутренним представлением в объекте, обычно это массив, содержащий значения и выражения. Каждая часть запроса имеет различную структуру.
Единственным аргументом метода getPart()
является
строка, идентифицирующая часть запроса, которую требуется
вернуть. Например, строка 'from'
соответствует той
части запроса, которая хранит информацию о таблицах в
предложении FROM
, включая присоединяемые таблицы.
Zend_Db_Select определяет константы, которые вы можете использовать для частей SQL-запроса. Вы можете использовать эти константы или литеральные строки.
Константа | Строковое значение |
---|---|
Zend_Db_Select::DISTINCT |
'distinct' |
Zend_Db_Select::FOR_UPDATE |
'forupdate' |
Zend_Db_Select::COLUMNS |
'columns' |
Zend_Db_Select::FROM |
'from' |
Zend_Db_Select::WHERE |
'where' |
Zend_Db_Select::GROUP |
'group' |
Zend_Db_Select::HAVING |
'having' |
Zend_Db_Select::ORDER |
'order' |
Zend_Db_Select::LIMIT_COUNT |
'limitcount' |
Zend_Db_Select::LIMIT_OFFSET |
'limitoffset' |
Example #30 Пример использования метода getPart()
Через метод reset()
вы можете очистить
определенную часть SQL-запроса или все части запроса, если
опустить аргумент.
Единственный аргумент метода является опциональным. Вы можете
указать часть запроса для очистки, используя те же строки,
которые используются для метода getPart()
. Та часть
запроса, которую вы указали, сбрасывается в состояние по
умолчанию.
Если вы опустите этот параметр, то reset()
сбрасывает все части запроса в состояние по умолчанию. Это
делает объект Zend_Db_Select эквивалентным новому объекту - так
же, как если бы вы его только что инстанцировали его.
Example #31 Пример использования метода reset()