Работаем с базой данных в Drupal 7 с помощью Database API

Выборка данных (SELECT запросы)

Для создания SELECT запросов в Drupal 7 используется функция db_select().

Рассмотрим примеры:

Простой запрос выборки nid и title из таблицы node где nid >= 5.

//SQL запрос
SELECT n.nid, n.title FROM node n WHERE n.nid >= 5
//php код
$query = db_select('node', 'n');
$query->fields('n', array('nid', 'title'));
$query->condition('n.nid', 5, '>=');
$result = $query->execute();

Получение количества записей в таблице node где nid > 10.

//SQL запрос
SELECT COUNT(*) FROM node n WHERE n.nid > 10
//php код
$query = db_select('node', 'n');
$query->fields('n');
$query->condition('n.nid', 10, '>');
$result = $query->execute()->rowCount();

Запрос с одним логическим оператором AND и оператором LIKE

//SQL запрос
SELECT n.nid, n.title FROM node n WHERE n.nid >= 5 AND n.title LIKE 'Chapter%'
//php код
$query = db_select('node', 'n');
$query->fields('n', array('nid', 'title'));
$query->condition('n.nid', 5, '>=');
$query->condition('n.title', 'Chapter%', 'LIKE');
$result = $query->execute();

Запрос c использованием логического оператора OR

//SQL запрос
SELECT n.nid, n.title FROM node n WHERE n.nid = 10 OR n.nid = 20
//php код
$query = db_select('node', 'n');
$query->fields('n', array('nid', 'title'));
 
$or = db_or();
$or->condition('n.nid', 10);
$or->condition('n.nid', 20);
 
$query->condition($or);
$result = $query->execute();

Запрос c использованием оператора BETWEEN

//SQL запрос
SELECT n.nid, n.title FROM node n WHERE n.nid BETWEEN 1 AND 10
//php код
$between = array(1, 10);
 
$query = db_select('node', 'n');
$query->fields('n', array('nid', 'title'));
$query->condition('n.nid', $between, 'BETWEEN');
$result = $query->execute();

Запрос c использованием оператора IN

//SQL запрос
SELECT n.nid, n.title FROM node n WHERE n.nid IN (1, 5, 10, 11)
//php код
$in = array(1, 5, 10, 11);
 
$query = db_select('node', 'n');
$query->fields('n', array('nid', 'title'));
$query->condition('n.nid', $in, 'IN');
$result = $query->execute();

Запрос c использованием оператора объединения LEFT JOIN и оператора IS NULL

//SQL запрос
SELECT n.title FROM node n
LEFT JOIN field_data_field_city fc ON fc.entity_id = n.nid
WHERE fc.field_city_value IS NULL
//php код
$query = db_select('node', 'n');
$query->fields('n', array('title'));
$query->leftJoin('field_data_field_city', 'fc', 'fc.entity_id = n.nid');
$query->isNull('fc.field_city_value');
$result = $query->execute();

Запрос c использованием оператора объединения INNER JOIN

//SQL запрос
SELECT u.name, n.title FROM node n
INNER JOIN users u ON u.uid = n.uid
WHERE u.uid = 1
//php код
$query = db_select('node', 'n');
$query->fields('u', array('name'));
$query->fields('n', array('title'));
$query->innerJoin('users', 'u', 'u.uid = n.uid');
$query->condition('u.uid', 1);
$result = $query->execute();

В случае сложных условий можно использовать метод where как в следующем примере

//SQL запрос
SELECT n.title FROM node n
WHERE FROM_UNIXTIME(n.created) < CURDATE() - INTERVAL 1 DAY
//php код
$query = db_select('node', 'n');
$query->fields('n', array('title'));
$query->where('FROM_UNIXTIME(:created) < CURDATE() - INTERVAL 1 DAY', array(':created' => $timestamp));
$result = $query->execute();

Запрос с использованием функции агрегации SUM с группировкой

//SQL запрос
SELECT SUM(vv.value) AS vote_sum, vv.entity_id, n.title FROM votingapi_vote vv
INNER JOIN node n ON n.nid = vv.entity_id
GROUP BY n.nid
//php код
$query = db_select('votingapi_vote', 'vv');
$query->addExpression('SUM(vv.value)', 'vote_sum');
$query->fields('vv', array('entity_id'));
$query->fields('n', array('title'));
$query->innerJoin('node', 'n', 'n.nid = vv.entity_id');
$query->groupBy('n.nid');
$result = $query->execute();

Запрос с использованием подзапроса (subquery)

//SQL запрос
SELECT n.title FROM node n
WHERE n.nid IN (SELECT ct.nid FROM custom_table ct)
//php код
$query = db_select('node', 'n');
$query->fields('n', array('title'));
 
$subquery = db_select('custom_table', 'ct');
$subquery->fields('ct', array('nid'));
 
$query->condition('n.nid', $subquery, 'IN');
$result = $query->execute();

Запрос с использованием оператора LIMIT

//SQL запрос
SELECT n.title FROM node n
LIMIT 2, 10
//php код
$query = db_select('node', 'n');
$query->fields('n', array('title'));
$query->range(2, 10);
$result = $query->execute();

Для получаения даных из результирующего набора можно использовать следующие функции:

fetchField($index = 0) - получение значения поля с индексом $index.

Эта функция часто используется для получения данных из запроса который возвращает только одну запись.

Пример использования:

$field_value = $result->fetchField();

fetchAssoc() - получение записи в виде ассоциативного массива

Пример использования:

$row = $result->fetchAssoc();

fetchObject() - получение записи в виде объекта

Пример использования:

$row = $result->fetchObject();

fetchAllKeyed($key_index = 0, $value_index = 1) - получение ассоциативного массива в котором ключем является поле с индексом $key_index, а значением поле с индексом $value_index. Массив формируется путем обхода всех записей. Обычно используется для запросов возвращающих только два поля.

Пример использования:

$result_array = $result->fetchAllKeyed(1, 0);

rowCount() - получения количества записей

Пример использования:

$count = $result->rowCount();

Также все записи можно обойти используя оператор цикла foreach при этом записи будут вытягиваться в виде объектов

Пример использования:

foreach ($result as $row) {
  //какие-то действия
}

Добавление записи (INSERT запросы)

Для добавления записей используется функция db_insert() .

Пример:

Добавление новой записи в таблицу node

//SQL запрос
INSERT INTO node (title, uid, type) VALUES ('New node', 1, 'article')
//php код
db_insert('node')
  ->fields(array(
    'title' => 'New node',
    'uid' => 1,
    'type' => 'article',
  ))
  ->execute();

Обновление записи (UPDATE запросы)

Для обновления записей используется функцияdb_update().

Примеры:

Обновление записи в таблице node где nid = 1

//SQL запрос
UPDATE node SET title = 'Updated', changed = 1363104629  WHERE nid = 1
//php код
$query = db_update('node');
$query->fields(array(
  'title' => 'Updated',
  'changed' => REQUEST_TIME,
));
$query->condition('nid', 1);
$num_updated = $query->execute();

Обновление всех полей title в таблице node где nid > 10

//SQL запрос
UPDATE node SET title = CONCAT(title, '(updated)') WHERE nid > 10
//php код
$query = db_update('node');
$query->expression('title', 'CONCAT(title, :suffix)', array(':suffix' => ' (updated)'));
$query->condition('nid', 10, '>');
$num_updated = $query->execute();

Удаление записи (DELETE запросы)

Для удаления записей используется функцияdb_delete().

Пример:

Удаление всех записей из таблицы node где nid > 10

//SQL запрос
DELETE FROM node WHERE nid > 10
//php код
$query = db_delete('node');
$query->condition('nid', 10, '>');
$num_deleted = $query->execute();
Поделись с друзьями:

Комментарии

Привет. Я имею самое непосредственное отношение к этому модулю. Я его написал :) Это мой первый и пока единственный официальный модуль на drupal.org. Приятно что кто-то успел заметить его и даже подготовить статью. Когда будет вермя подготовлю статью о нем  в своем блоге тоже. 

Добрый день.

Скажите пожалуйста, а каким образом можно модифицировать запрос ?

Допустим, я клонировал некий запрос и хочу в новом запросе удалить какие-либо поля или изменить условия.

Так и сделать: удалить поля или изменить условия :) Что конкретно вы хотите поменять?

Столкнулся с проблемой что на сайте все работает хорошо но при попытке сделать drush cc all получаю WD menu: PDOException: SQLSTATE[42000] проблема оказалась в том что если у вас несколько запросов подряд и например результат первого запроса служит какм либо параметров для второго, не поленитесь сделать дополнительную проверку на что данные из первого запроса всетаки получены и сохранены.

Меня спасла прверка на epmty переменной в которой храниться результат из предыдущего запроса.

Надеюсь кому нибуть поможет.

За сайт и конкретно этот пост автору спасибо!

Нужна помощь!!) Необходимо сделать реферальную систему 5 уровней, есть табличка с колонками uid, р1, р2, р3... в куке висит id реферала ( для нового пользователя он будет р1) как сделать запрос к базе данных чтобы при регистрации нового пользователя он выбрал по условию $cookie['uid'] = uid и записал его в поля р1 => $cookie['uid'], p2 => p1(реферала), р3 => р2(реферала) и т.д... уже перепробовал много способов написать такой - ни одного успешного((( вот один из них:
$query = db_select('referral', 'r');
$query
->condition('uid', $cookie['uid'], '=')
->fields('r', array('referral_uid', 'r2_uid', 'r3_uid', 'r4_uid'));
$query = db_insert('referral')
->fields(array(
'uid' => $uid,
'referral_uid' => $cookie['uid'],
'r2_uid' => 'r.referral_uid',
'r3_uid' => 'r.r2_uid',
'r4_uid' => 'r.r3_uid',
'r5_uid' => 'r.r4_uid',
'created' => $cookie['timestamp'],
'host' => $cookie['ip'],
'http_referer' => $cookie['referer'],
))
->execute();
}

Это вопрос не по Drupal. Хотя из вашего кода я совсем ничего не понял. Сперва в $query вы записываете db_select, а потом перетираете его db_insert.

если в двух словах - то мне надо взять из таблицы данные по условию совпадения uid и вставить их в туже таблицу но в другие колонки...

Доброго времени!!
Нужна помощь!.. Не очень силен в api , да и в самом php начинающий.
Суть: Нужно обновить одно поле таблицы, то есть все его значения , например, умножить на 2.
Как это сделать прпавильно срeдствами Drupal7 ?

$q = db_select('field_data_commerce_price', 'tt');
$q->fields('tt', array('revision_id', 'commerce_price_amount'));
$res = $q->execute();

$arg = $form_state['values']['coef'];
$row = array();

while($row = $res->fetchAssoc()){
$row['commerce_price_amount'] *= $arg;
//debug($row['commerce_price_amount']);
$qq = db_update('field_data_commerce_price', 'ttt');
$qq -> fields( array ( 'commerce_price_amount' => $arg));
$ress = $qq -> execute();
}

Прошу не смеяться сразу очень ). Сам дойти не могу, а спросить не у кого.

Буду безмерно благодарен за помощь!!!
Спасибо!.

Понятно