Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll

Работа с БД в Drupal 7 - урок 12 - Условия запросов (WHERE, HAVING, LIKE)

02/12/2019, by Ivan

Условие запроса позволяет выбрать только те записи, которые подходят под некоторые ограничения, например ноды созданные не раньше двух недель назад, термины в которых есть слово "друпал" и т.д. В SQL мы используем WHERE и HAVING чтобы задать ограничения на запросы SELECT, UPDATE, DELETE. В динамических запросах также реализован механизм для работы с условиями запросов. Этот механизм работает одинаково для всех трех типов запросов: выбора, обновления, удаления.

Концепция условных выражений

Условие содержится в специальном выражение задающем ограничение.

Объединение(сложение, конъюнкция)

Каждое условие может состоять из нескольких выражений условий, которые объединяются вместе. Условия объединяются с помощью операторов AND ( И ) и OR (ИЛИ)

Объект условия

Друпал представляет каждый фрагмент условия как экземпляр класса QueryConditional. Объект условия это экземпляр класса QueryConditional.

Давайте рассмотрим пример SQL-запроса:

Запрос:

SELECT FROM {mytable} WHERE (a = 1 AND b = 'foo' OR (c = 'bar'))

Выражение условия:

WHERE (a = 1 AND b = 'foo' OR (c = 'bar'))

Части выражения условия:

(a = 1 AND b = 'foo' OR (c = 'bar'))
(c = 'bar')

Операторы соединения условий:

AND, OR

Объекты запросов SELECT, UPDATE, DELETE реализуются через класс QueryConditionalInterface, который предоставляет интерфейсы для каждого из трех видов запросов. Далее этот объект оборачивается в объект QueryConditional. Класс QueryConditional можно вызывать напрямую.

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

 

API

Есть два главных метода использовать все объекты условий:

$query->condition($field, $value = NULL, $operator = '=')

Метод condition() позволяет определить поле, значение и оператор фрагмента условия запроса. Этот метод можно использовать для задания условий с бинарным сравнением (там где есть два вариант ПРАВДА или ЛОЖЬ) таких как =, <, >=, LIKE и так далее. Если оператор не определен, то по умолчанию используется = (то есть точное соответсвие). Таким образом для обычного сравнения можно писать condition('myfield', $value), что будет преобразовано в myfield = :value, где :value будет заменено на значение переменной $value.

$query->where($snippet, $args = array())

Метод where() дополнительный метод, потому что можно использовать condition() вместо where(). Но where() очень часто используется, поэтому его вынесли в отдельный метод. В перменной $snippet мы пишем обычный SQL запрос, а в переменной $args массив заменителей для запроса в $snippet.

Испольльзование condition() предпочтительнее использования where().

Условия с массивами

Бывает что для запросов нужно сформировать условие со множеством значений. Для этого в запрос мы передаем массив значений. Наиболее популярные операторы SQL в таких случаях IN и BETWEEN. Оператор IN пропускает только при точном совпадение с одним элементом в массиве.

<?php
$query->condition('myfield', array(1, 2, 3), 'IN');
// Становится: myfield IN (:db_placeholder_1, :db_placeholder_2, :db_placeholder_3)
?>

Таким образом мы выберим все записи в поле myfield которых значения 1,2 или 3.

Если нужно задать не точные значения, а диапазон значений, то мы используем BETWEEN:

<?php
$query->condition('myfield', array(5, 10), 'BETWEEN');
// Становится: myfield BETWEEN :db_placeholder_1 AND :db_placeholder_2
?>

Так мы выбираем все записи в поле myfield которых значения от 5 до 10.

Вложенные условия

Первый параметр condition() может принимать другие объект условия. Вложенный запрос может быть включен в другой более сложный запрос. В результате мы получим сложное условие соединеное где нужно операторами AND и OR.

Хелпер db_condition() возвращает новый объект условие. Этот метод имеет один параметр, а именно какой тип соединения условия он использует. Вы также можете использовать хелперы db_or(), db_xor() (все значения исключающие ИЛИ), db_and(), как правило этих готовых хелперов хватает. Давайте рассмотрим пример:

<?php
$query
  ->condition('field1', array(1, 2), 'IN')
  ->condition(db_or()->condition('field2', 5)->condition('field3', 6))
// В результате получится такой запрос:
// (field1 IN (:db_placeholder_1, :db_placeholder_2) AND (field2 = :db_placeholder3 OR field3 = :db_placeholder_4))
?>

Значения NULL

Для проверки значения NULL используйте следующие методы:

<?php
$query->isNull('myfield');
// Результат (myfield IS NULL)

$query->isNotNull('myfield');
// Результат (myfield IS NOT NULL)
?>

Эти методы isNull(), isNotNull() могут быть комбинированы с where(), condition().

Заметьте, что condition('myfield', NULL) устарело, используйте isNull(), isNotNull().

Подзапрос

Метод condition() поддерживает подзапросы для $value. Для использования подзапроса используется класс SelectQuery, который создается с помощью метода db_select(). Вместо выполнения метода select() объекту передаются параметры метода condition().

Подзапросы удобно использовать для коротких простых запросов с условием по одному полю. Если вы попытаетесь сделать что-то грандиозное с помощью db_select(), то лучше бросьте эту затею и используйте condition().

Давайте рассмотрим примеры подзапросов, чтобы стало яснее:

db_delete()

<?php
db_delete('sessions')
  ->condition('timestamp', REQUEST_TIME - $lifetime, '<')
  ->execute();
// DELETE FROM {sessions} WHERE (timestamp < 1228713473)
?>
db_update()
<?php
db_update('sessions')
  ->fields(array(
    'sid' => session_id()
  ))
  ->condition('sid', $old_session_id)
  ->execute();
// UPDATE {sessions} SET sid = 'abcde' WHERE (sid = 'fghij');
?>

db_delete()

<?php
// From taxonomy_term_save():
$or = db_or()->condition('tid1', 5)->condition('tid2', 6);
db_delete('term_relation')->condition($or)->execute();
// DELETE FROM {term_relation} WHERE ((tid1 = 5 OR tid2 = 6))
?>