Drupal → Работа с базой данных

30.03.2010

Выборка с условием:

// Drupal 6
$nodes = db_query("
  SELECT nid, title
  FROM {node}
  WHERE type = '%s' AND uid = %d
", 'page', 1);

// Drupal 7, static query
$nodes = db_query("
  SELECT nid, title
  FROM {node}
  WHERE type = :type AND uid = :uid
", array(':type' => 'page', ':uid' => 1))->fetchAll();

// Drupal 7, dynamic query
$nodes = db_select('node', 'n')
  ->fields('n', array('nid', 'title'))
  ->condition('n.type', 'page') // <--
  ->condition('n.uid', 1) // <--
  ->execute()
  ->fetchAll();

// Drupal 8+
$nodes = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n', ['nid', 'title'])
  ->condition('n.type', 'page') // <--
  ->condition('n.uid', 1) // <--
  ->execute()
  ->fetchAll();

Выборка из двух таблиц соединённых с помощью INNER JOIN:

// Drupal 6
$nodes = db_query("
  SELECT n.title, u.name
  FROM {node} n
  INNER JOIN {users} u ON n.uid = u.uid
");

// Drupal 7, static query
$nodes = db_query("
  SELECT n.title, u.name
  FROM {node} n
  INNER JOIN {users} u ON n.uid = u.uid
")->fetchAll();

// Drupal 7, dynamic query
$query = db_select('node', 'n');
$query->innerJoin('users', 'u', 'n.uid = u.uid'); // <--
$query->fields('n', array('title'));
$query->fields('u', array('name'));
$nodes = $query->execute()->fetchAll();

// Drupal 8+
$query = \Drupal::database()->select('node_field_data', 'n');
$query->innerJoin('users_field_data', 'u', 'n.uid = u.uid'); // <--
$query->fields('n', ['title']);
$query->fields('u', ['name']);
$nodes = $query->execute()->fetchAll();

Следует помнить, что некоторые методы (например джоины) не возвращают объект SelectQuery, и поэтому их нельзя использовать в цепочке вызовов вроде db_select()->method1()->innerJoin()->method2().

Получить значение поля у единственной записи:

// Drupal 6
$title = db_result(db_query("
  SELECT title
  FROM {node}
  WHERE nid = %d
", 123));

// Drupal 7, static query
$title = db_query("
  SELECT title
  FROM {node}
  WHERE nid = :nid
", array(':nid' => 123))->fetchField();

// Drupal 7, dynamic query
$title = db_select('node', 'n')
  ->fields('n', array('title'))
  ->condition('n.nid', 123)
  ->execute()
  ->fetchField(); // <--
  
// Drupal 8+
$title = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n', ['title'])
  ->condition('n.nid', 123)
  ->execute()
  ->fetchField(); // <--

Получить объект по его id:

// Drupal 6
$node = db_fetch_object(db_query("
  SELECT *
  FROM {node}
  WHERE nid = %d
", 123));

// Drupal 7, static query
$node = db_query("
  SELECT *
  FROM {node}
  WHERE nid = :nid
", array(':nid' => 123))->fetchObject();

// Drupal 7, dynamic query
$node = db_select('node', 'n')
  ->fields('n')
  ->condition('n.nid', 123)
  ->execute()
  ->fetchObject(); // <--
  
// Drupal 8+
$node = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n')
  ->condition('n.nid', 123)
  ->execute()
  ->fetchObject(); // <--

Посчитать число записей:

// Drupal 6
$count = db_result(db_query("
  SELECT COUNT(*)
  FROM {node} n
  WHERE n.uid = 1
"));

// Drupal 7, static query
$count = db_query("
  SELECT COUNT(*)
  FROM {node} n
  WHERE n.uid = 1
")->fetchField();

// Drupal 7, dynamic query, вариант 1
$count = db_select('node', 'n')
  ->condition('n.uid', 1)
  ->countQuery() // <--
  ->execute()
  ->fetchField();

// Drupal 7, dynamic query, вариант 2
$query = db_select('node');
$query->addExpression('COUNT(*)'); // <--
$count = $query->execute()->fetchField();

// Drupal 8+, вариант 1
$count = \Drupal::database()
  ->select('node_field_data', 'n')
  ->condition('n.uid', 1)
  ->countQuery() // <--
  ->execute()
  ->fetchField();
  
// Drupal 8+, вариант 2
$query = \Drupal::database()->select('node_field_data');
$query->addExpression('COUNT(*)'); // <--
$count = $query->execute()->fetchField();

Найти минимальное значение:

// Drupal 6
$min = db_result(db_query("SELECT MIN(fieldname) FROM {tablename}"));

// Drupal 7, static query
$min = db_query("SELECT MIN(fieldname) FROM {tablename}")->fetchField();

// Drupal 7, dynamic query
$query = db_select('tablename');
$query->addExpression('MIN(fieldname)'); // <--
$min = $query->execute()->fetchField();

// Drupal 8+
$query = \Drupal::database()->select('tablename');
$query->addExpression('MIN(fieldname)'); // <--
$min = $query->execute()->fetchField();

Выбрать определённое количество записей:

// Drupal 6
$nodes = db_query("SELECT * FROM {node} LIMIT 0, 10");

// Drupal 7, static query
$nodes = db_query("SELECT * FROM {node} LIMIT 0, 10")->fetchAll();

// Drupal 7, dynamic query
$nodes = db_select('node', 'n')
  ->fields('n')
  ->range(0, 10) // <--
  ->execute()
  ->fetchAll();
  
// Drupal 8+
$nodes = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n')
  ->range(0, 10) // <--
  ->execute()
  ->fetchAll();

Обойти записи:

// Drupal 6
$nodes = db_query("SELECT * FROM {node}");
while ($node = db_fetch_object($nodes)) {
  $items[] = $node->title;
}

// Drupal 7, static query
$result = db_query("SELECT * FROM {node}");
foreach ($result as $node) {
  $items[] = $node->title;
}

// Drupal 7, dynamic query
$result = db_select('node', 'n')->fields('n')->execute();
foreach ($result as $row) {
  $items[] = $row->title;
}

// Drupal 8+
$result = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n')
  ->execute();
foreach ($result as $row) {
  $items[] = $row->title;
}

Обновление записи:

// Drupal 6
db_query("UPDATE {node} SET status = %d WHERE nid = %d", 1, 123);

// Drupal 7, static query
db_query("
  UPDATE {node}
  SET status = :status
  WHERE nid = :nid
", array(':status' => 1, ':nid' => 123));

// Drupal 7, dynamic query
db_update('node')
  ->fields(array('status' => 1))
  ->condition('nid', 123)
  ->execute();
  
// Drupal 8+
\Drupal::database()
  ->update('node_field_data')
  ->fields(['status' => 1])
  ->condition('nid', 123)
  ->execute();

Инкремент значения поля:

// Drupal 6
db_query("
  UPDATE {node_counter}
  SET totalcount = totalcount + 1
  WHERE nid = %d
", 123);

// Drupal 7, static query
db_query("
  UPDATE {node_counter}
  SET totalcount = totalcount + 1
  WHERE nid = :nid
", array(':nid' => 123));

// Drupal 7, dynamic query
db_update('node_counter')
  ->expression('totalcount', 'totalcount + 1')
  ->condition('nid', 123)
  ->execute();
  
// Drupal 8+
\Drupal::database()
  ->update('node_counter')
  ->expression('totalcount', 'totalcount + 1')
  ->condition('nid', 123)
  ->execute();

Удаление записи:

// Drupal 6
db_query("
  DELETE FROM {node}
  WHERE uid = %d AND created < %d
", 1, time() - 3600);

// Drupal 7, static query
db_query("
  DELETE FROM {node}
  WHERE uid = :uid AND created < :created
", array(':uid' => 1, ':created' => time() - 3600));

// Drupal 7, dynamic query
db_delete('node')
  ->condition('uid', 1)
  ->condition('created', time() - 3600, '<')
  ->execute();
  
// Drupal 8+
\Drupal::database()
  ->delete('node_field_data')
  ->condition('uid', 1)
  ->condition('created', time() - 3600, '<')
  ->execute();

Очистка таблицы (удаление всех данных из таблицы):

// Drupal 6, Drupal 7 static query
db_query("TRUNCATE {watchdog}");

// Drupal 7, dynamic query
db_truncate('watchdog')->execute();

// Drupal 8+
\Drupal::database()->truncate('watchdog')->execute();

Добавление записи:

// Drupal 6
db_query("
  INSERT INTO {mytable} (intvar, stringvar, floatvar)
  VALUES (%d, '%s', %f)
", 5, 'hello world', 3.14);
$id = db_last_insert_id();

// Drupal 7, dynamic query
$id = db_insert('mytable')
  ->fields(array(
    'intvar' => 5,
    'stringvar' => 'hello world',
    'floatvar' => 3.14,
  ))
  ->execute();
  
// Drupal 8+
$id = \Drupal::database()
  ->insert('mytable')
  ->fields([
    'intvar' => 5,
    'stringvar' => 'hello world',
    'floatvar' => 3.14,
  ])
  ->execute();

Использование логического оператора OR в условии:

// Drupal 6
$nodes = db_query("
  SELECT *
  FROM {node}
  WHERE type = 'page' AND (uid = %d OR status = %d)
", 1, 0);

// Drupal 7, static query
$nodes = db_query("
  SELECT *
  FROM {node}
  WHERE type = 'page' AND (uid = :uid OR status = :status)
", array(':uid' => 1, ':status' => 0))->fetchAll();

// Drupal 7, dynamic query
$nodes = db_select('node', 'n')
  ->fields('n')
  ->condition('n.type', 'page')
  ->condition(
    db_or()
      ->condition('n.uid', 1)
      ->condition('n.status', 0)
  )
  ->execute()
  ->fetchAll();
  
// Drupal 8+
$query = \Drupal::database()
  ->select('node_field_data', 'n');
  ->fields('n')
  ->condition('n.type', 'page');
$or_conditions = $query->orConditionGroup();
$or_conditions->condition('n.uid', 1);
$or_conditions->condition('n.status', 0);
$query->condition($or_conditions);

Использование оператора IN в условии:

$nids = array(1, 2, 3);

// Drupal 6
$nodes = db_query("
  SELECT *
  FROM {node}
  WHERE nid IN (" . db_placeholders($nids) . ")
", $nids);

// Drupal 7, static query
$nodes = db_query("
  SELECT *
  FROM {node}
  WHERE nid IN (:nids)
", array(':nids' => $nids))->fetchAll();

// Drupal 7, dynamic query
$nodes = db_select('node', 'n')
  ->fields('n')
  ->condition('n.nid', $nids, 'IN')
  ->execute()
  ->fetchAll();
  
// Drupal 8+
$nodes = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n')
  ->condition('n.nid', $nids, 'IN')
  ->execute()
  ->fetchAll();

Использование оператора LIKE в условии:

// Drupal 6
$nodes = db_query("
  SELECT *
  FROM {node}
  WHERE title LIKE '%%%s%%'
", 'substring');

// Drupal 7, static query
$nodes = db_query("
  SELECT *
  FROM {node}
  WHERE title LIKE :title
", array(':title' => '%' . db_like('substring') . '%'))->fetchAll();

// Drupal 7, dynamic query
$nodes = db_select('node', 'n')
  ->fields('n')
  ->condition('n.title', '%' . db_like('substring') . '%', 'LIKE')
  ->execute()
  ->fetchAll();
  
// Drupal 8+
$nodes = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n')
  ->condition('n.title', '%' . \Drupal::database()->escapeLike('substring') . '%', 'LIKE')
  ->execute()
  ->fetchAll();

Использование оператора BETWEEN в условии:

// Drupal 6
$nodes = db_query("
  SELECT *
  FROM {node}
  WHERE nid BETWEEN %d AND %d
", 123, 456);

// Drupal 7, static query
$nodes = db_query("
  SELECT *
  FROM {node}
  WHERE nid BETWEEN :nid1 AND :nid2
", array(':nid1' => 123, ':nid2' => 456))->fetchAll();

// Drupal 7, dynamic query
$nodes = db_select('node', 'n')
  ->fields('n')
  ->condition('n.nid', array(123, 456), 'BETWEEN')
  ->execute()
  ->fetchAll();
  
// Drupal 8+
$nodes = \Drupal::database()
  ->select('node', 'n')
  ->fields('n')
  ->condition('n.nid', [123, 456], 'BETWEEN')
  ->execute()
  ->fetchAll();

Проверка значения на NULL:

// Drupal 6, Drupal 7 static query
$result = db_query("SELECT * FROM {tablename} WHERE fieldname IS NULL");

// Drupal 7, dynamic query, вариант 1
$result = db_select('tablename', 't')
  ->fields('t')
  ->condition('t.fieldname', NULL, 'IS NULL')
  ->execute();

// Drupal 7, dynamic query, вариант 2
$result = db_select('tablename', 't')
  ->fields('t')
  ->isNull('t.fieldname')
  ->execute();
  
// Drupal 8+
$result = \Drupal::database()
  ->select('tablename', 't')
  ->fields('t')
  ->isNull('t.fieldname')
  ->execute();

Сложные условия в WHERE:

// Drupal 6
$nodes = db_query("
  SELECT *
  FROM {node}
  WHERE YEAR(FROM_UNIXTIME(created)) = %d
", 2011);

// Drupal 7, static query
$nodes = db_query("
  SELECT *
  FROM {node}
  WHERE YEAR(FROM_UNIXTIME(created)) = :created
", array(':created' => 2011))->fetchAll();

// Drupal 7, dynamic query
$nodes = db_select('node', 'n')
  ->fields('n')
  ->where('YEAR(FROM_UNIXTIME(n.created)) = :created', array(':created' => 2011))
  ->execute()
  ->fetchAll();
  
// Drupal 8+
$nodes = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n')
  ->where('YEAR(FROM_UNIXTIME(n.created)) = :created', [':created' => 2011])
  ->execute()
  ->fetchAll();

Сортировка:

// Drupal 6
$nodes = db_query("
  SELECT *
  FROM {node}
  ORDER BY created DESC, title ASC
");

// Drupal 7, static query
$nodes = db_query("
  SELECT *
  FROM {node}
  ORDER BY created DESC, title ASC
")->fetchAll();

// Drupal 7, dynamic query
$nodes = db_select('node', 'n')
  ->fields('n')
  ->orderBy('n.created', 'DESC')
  ->orderBy('n.title', 'ASC')
  ->execute()
  ->fetchAll();
  
// Drupal 8+
$nodes = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n')
  ->orderBy('n.created', 'DESC')
  ->orderBy('n.title', 'ASC')
  ->execute()
  ->fetchAll();

Получить результаты запроса в виде двумерного ассоциативного массива:

// Drupal 6
$result = db_query("SELECT nid, title, created FROM {node}");
$nodes = array();
while ($row = db_fetch_object($result)) {
  $nodes[$row->nid] = $row;
}

// Drupal 7, static query
$nids = db_query("SELECT nid, title, created FROM {node}")->fetchAllAssoc('nid');

// Drupal 7, dynamic query
$nids = db_select('node', 'n')
  ->fields('n', array('nid', 'title', 'created'))
  ->execute()
  ->fetchAllAssoc('nid');
  
// Drupal 8+
$nids = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n', ['nid', 'title', 'created'])
  ->execute()
  ->fetchAllAssoc('nid'); // или fetchAllAssoc('nid', PDO::FETCH_ASSOC) если дочерние элементы нужны в виде массива, а не stdClass

Получить одну колонку из таблицы в виде простого одномерного массива:

// Drupal 6
$result = db_query("SELECT nid FROM {node}");
$nids = array();
while ($row = db_fetch_object($result)) {
  $nids[] = $row->nid;
}

// Drupal 7, static query
$nids = db_query("SELECT nid FROM {node}")->fetchCol();

// Drupal 7, dynamic query
$nids = db_select('node', 'n')
  ->fields('n', array('nid'))
  ->execute()
  ->fetchCol();
  
// Drupal 8+
$nids = \Drupal::database()
  ->select('node', 'n')
  ->fields('n', ['nid'])
  ->execute()
  ->fetchCol();

Получить одномерный ассоциативный массив, где ключами будет первая колонка запроса, а значениями — вторая:

// Drupal 6
$result = db_query("SELECT nid, title FROM {node}");
$titles = array();
while ($row = db_fetch_object($result)) {
  $nids[$row->nid] = $row->title;
}

// Drupal 7, static query
$titles = db_query("SELECT nid, title FROM {node}")->fetchAllKeyed();

// Drupal 7, dynamic query
$titles = db_select('node', 'n')
  ->fields('n', array('nid', 'title'))
  ->execute()
  ->fetchAllKeyed();
  
// Drupal 8+
$titles = \Drupal::database()
  ->select('node_field_data', 'n')
  ->fields('n', ['nid', 'title'])
  ->execute()
  ->fetchAllKeyed();

Полный мануал с кучей примеров есть на официальном сайте — Database API.

Написанное актуально для
Drupal 6, Drupal 7, Drupal 8+
Похожие записи

Комментарии

Азаров
03.04.2010, 10:39

php5
красава... :)
наконец то. главное с db_delete() не наделать хренотени

Гость
14.08.2010, 02:38

Вот это да! Как все намного проще будет делать! ООП рулит!

Антон Гаренских
10.02.2011, 22:37

Вах , блин я седня полвечера убил и ничего по теме не нашел. А твой сайт просто супер ! Drupal 7 вроде недавно появилась, а у тебя уже актуальная информация. Спасибо !

Петров Николай
28.05.2011, 18:14

Отличный справочный материал!
Спасибо за статью.

Гость
06.06.2011, 13:13

А как реализовать такую конструкцию? $query->condition('YEAR(FROM_UNIXTIME(c.dateborn))', $edit->dateborn_year, '='); Запрос с таким условием не работает, т.к скобки удаляются.

$query->where('YEAR(FROM_UNIXTIME(c.dateborn)) = :dateborn', array(':dateborn' => $edit->dateborn_year));
Гость
19.06.2011, 13:47

а как узнать, что, например, при получении строки через
Обойти записи:

// Drupal 7
$nodes = db_select('node', 'n')->fields('n')->execute(); // или $nodes = db_query("SELECT * FROM {node}");
foreach ($nodes as $node) {
$items[] = $node->title;
}

запрос вернет false? вроде в любом случае там объект возвращается. даже если строки такой нету.

Гость
19.06.2011, 16:57

*как узнать, что... запрос вернет false?

Гость
19.06.2011, 17:30

это плохо. как узнать что такой запрос не выдаст ничего? неохота делать ещё 1 запрос на кол-во записей. можно конечно сделать проверку на значения переменных после цикла -- но это как-то коряво.

Анатолий
20.06.2011, 10:35

Люди подскажите пожалуйста, вот код:

$query = db_select('public.lico', 't1');
$query -> fields('t1');
$query -> condition('t1.key', 30, '>')
       -> condition('t1.key', 50, '<');

Выполнение данного запроса должно вывести двумерный массив, типа:

+---------+-------+-----------+
| Фамилия |  Имя  |  Отчество |
+---------+-------+-----------+
| Иванов  | Иван  | Иванович  |
| Петров  | Петр  | Петрович  |
| Сидоров | Сидор | Сидорович |
+---------+-------+-----------+

Так вот вопрос: подскажите, как мне правильно обойти строки?

Если запрос закончить так:

$result = $query -> execute() -> fetchAssoc();
$output = '';
            
foreach($result as $index => $value) {
  $output = $output.'Индекс элемента массива = '. $index .', значение = '.$value . "<br>";
}

выводит только одну строку...

если написать типа:

$result = $query -> execute();
$output = '';
            
foreach($result as $row) {
  $output = $output. $row->title;
}

Пишет ошибку:

Notice: Undefined property: stdClass::$title...

Объясните, что я делаю не так? Только не пинайте сильно, недавно начал разбираться в друпале...
P.S. БД у меня PostgreSQL

Анатолий
20.06.2011, 15:28

Всё, разобрался. Блин с субботы мучился и никак, а тут раз, и получилось.
Вот как закончил запрос, и вывело так как мне нужно:

$result = $query -> execute();
$output = '';
            
while ($record = $result->fetchAssoc()) { 
    foreach($record as $index => $value) {
        $output = $output.'index = '. $index .', value = '.$value . " | ";
    }
    $output = $output."<br>";
}

З.Ы. Может кому полезно будет, сэкономлю пару минут)

Еще важно для выборок материалов не забывать добавлять тег:

->addTag('node_access');
Гость
13.08.2011, 15:53

Здравствуйте, сделал запрос, а вывести не могу, как это делается?
$nodes = db_select('users', 'n')
->fields('n')
->execute();
для начала хоть целеком таблицу вывести, а потом буду копаться как сделать поиск с формы (несколько полей на форме) по таблице.

Александр
16.08.2011, 01:03

подскажите, пожалуйста, как быть с подзапросом:

INSERT INTO table VALUES field = (SELECT field2 FROM table2 WHERE id=$id)

И насколько это правильно. Спасибо

Александр
17.08.2011, 12:49

А что в таком случае будет правильным решением? Спасибо.

Александр
17.08.2011, 13:43

Правильно ли так получиться

$subquery = db_select('node', 'n');
    $subquery->fields('n', array('nid'));
    $subquery->condition("n.title = {$node->manufactures}");
 
    $query = db_insert(" field_revision_field_{$node->type}_manufactures", 'f')->fields('f', array
    (
      'entity_type' => 'node',
      'bundle' => $node->type,
      'deleted' => 0,
      'entity_id' => $node->nid,
      'revision_id' => $node->nid,
      'language' => 'und',
      'delta' => 0,
      'field_footwear_type_tid' => manufactures_id,
    ));
    $query->addExpression("({$subquery})", 'manufactures_id');
    $id = $query->execute();

хотел получить:

"INSERT INTO field_revision_field_{$node->type}_manufactures (entity_type, ...) VALUES ('node', ..., (SELECT n.nid FROM node as n WHERE n.title = '$node->manufactures'));";

А что в таком случае будет правильным решением?

сделать два запроса

chyvakoff
17.08.2011, 14:36

Как извлечь дату в формате FROM_UNIXTIME(DateTimeStart, '%Y-%m-%d') AS date
поле DateTimeStart формата int.Изменить тип поля в БД нельзя.
Извлечь обычный интегер и потом на стороне пхп преобразовать функцией date тоже нельзя,так по этому полю будет GROUP BY

$query->addExpression("FROM_UNIXTIME(DateTimeStart, '%Y-%m-%d')", 'date');
chyvakoff
17.08.2011, 14:47

Блин..тоже самое же делал, и не получалось почему то...
Спасибо;)

Влад Стратулат
25.08.2011, 19:11

Спасибо xandeadx
Отлично вывел "все" примеры работы с базой.

У меня вопрос касательно ->fetchObject()

// Пример 1: выдает объект ноды
$node = db_select('node', 'n')
	->fields('n')
	->condition('n.nid', 6)
	->execute()
	->fetchObject();

// Пример 2: выдает объект запроса
$blog = db_select('node', 'n');
$blog
	->leftJoin('field_data_body', 'b', 'b.revision_id = n.vid');
$blog
	->fields('b')
	->condition('n.nid', 6)
	->execute()
	->fetchObject();

Как мне во втором примере получить объект ноды?
Спасибо!

Влад Стратулат
25.08.2011, 19:18

Разобрался сам! Привожу код, может кому поможет.

$query = db_select('node', 'n');
$query
	->leftJoin('field_data_body', 'b', 'b.revision_id = n.vid');
$query
	->fields('b')
	->condition('n.nid', $bid);

$result = $query->execute();
$blog = $result->fetchObject();
Александр
26.08.2011, 10:34

Подскажите, пожалуйста, как быть с условием IF NOT EXISTS. Спасибо.

Александр
26.08.2011, 12:02

И еще с запросом типа:

SELECT IF(условие, истина, лож)
addExpression('IF(условие, истина, лож)')
bigferumdron@gmail.com
13.11.2011, 23:42

Спасибо, за полезный материал. Скажите, вот составить простой запрос - задача решаемая. Но вот вытащить что-то сложное из базы с кучей джоинов...... Вот если в своем модуле, нужно выполнить какую-то сложную выборку, ведь можно ее сперва сделать через VIEWS , затем скопировать получившийся запрос и вставить в db_query() ?

Такое ведь возможно? Если да, то как правильно это делать? я никак не могу разобраться, уже все мозги выкипели.. Проблема в том, что НЕ достаются значения cck полей . Т.е. достается только id ноды и title ноды . Все дополнительные поля, не достаются.. Подскажите пожалуйста, почему? что я делаю не так... почему предпросмотр VIEWS при таком запросе выдает все результаты, а db_query нет?

Во вьюшке достаю 3 поля: title, body, field_delivery_cost . А когда делаю DSM полученного результата, вижу 4 строки:
node_title (String, 14 characters ) Заголовок тестовой ноды
nid (String, 2 characters ) 68
field_data_body_node_entity_type (String, 4 characters ) node
field_data_field_delivery_cost_node_entity_type (String, 4 characters ) node

Т.е. имеем только значение тайтла... + появилось значение айдишника ноды.. А значение поля BODY и кастомного поля - представлены в виде строки node ..

Выручайте....

для начала неплоха бы запрос предоставить, телепатическими способностями не обладаю

bigferumdron@gmail.com
14.11.2011, 10:09

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

SELECT node.title AS node_title, node.nid AS nid, 'node' AS field_data_body_node_entity_type, 'node' AS field_data_field_delivery_cost_node_entity_type FROM  {node} node

в запросе выбираются заголовки, nid-ы и две строки 'node'. результат ожидаемый

bigferumdron@gmail.com
14.11.2011, 13:03

Да уж, наверное так и есть... Тогда вопрос по другому. Можно ли поступить как я говорил, т.е. сгенерировать запрос во вьюхе, скопировать его и использовать? Из моей ситуации, я понимаю, что походу нет.. (в ситуации я запрос упростил значительно, чтобы была понятна суть..)

bigferumdron@gmail.com
14.11.2011, 16:18

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

Вадим
17.11.2011, 19:12

В чем может быть проблемма : Когда применяю

$query = db_select('node', 'n');
$query->innerJoin('users', 'u', 'n.uid = u.uid');
$query->fields('n', array('title'));
$query->fields('u', array('name'));
$result = $query->execute();

выдаёт ошибку Fatal error: Call to a member function field() on a non-object in и указывает на строку $query->fields('n', array('title'));

Гость
02.12.2011, 15:00

Эти запросы прямо в page.tpl.php можно писать да?

Подскажите почему конструкция:
$query->condition('p.forum_id', 1);
$query->condition('p.forum_id', 10);
превращается в:
WHERE (p.forum_id = :db_condition_placeholder_0) AND (p.forum_id = :db_condition_placeholder_1)

Почему так получается и как получить конкретные значения вместо :db_condition_placeholder_0?

И еще: как получить OR вместо AND для нескольких кондишинов?
Приходится делать так: $query->where('p.forum_id = 1 OR p.forum_id = 10');
А кондишинами так можно сделать?

Вадим
10.01.2012, 14:49

а можно еще и пример с UNION в случае когда в таблицах разное количество полей
делаю так, не получается

$t1= db_select('table1','t1')
        ->fields('t1',array('id','field1'));
$t2 = db_select('table2','t2')
        ->fields('t2',array('id',field2));
$t1 ->union($t2,'UNION ALL');
$result =$t1->execute();

При этом в table1 к примеру 5 полей, а в table2 только 2.

Андрей
31.01.2012, 00:51

Подскажите пожалуйста, а как правильно сформировать запрос с лайком, например такой:

SELECT title,id,efind_cat FROM {efind_element}  WHERE title LIKE '%ONE%' AND title LIKE '%TWO%'
Андрей
31.01.2012, 03:04

А зачем нужна функция db_like ? читал апи, но как-то недопонимаю..
почему нельзя написать так:

condition('title', '%ONE'%', 'LIKE')

Попробовал, вроде и так работает...

+ подскажите плиз, получается, что в condition по умолчанию используется оператор AND? т.е. если у нас двойное условие через AND, мы просто пишем
->condition1
->condition2

А если условие OR , тогда пользуемся db_or() ?

А зачем тогда нужно db_and() ?

P.S. Спасибо за ценный материал и за сайт!

А зачем нужна функция db_like ?

http://api.drupal.org/api/drupal/includes--database--database.inc/funct…

Escapes characters that work as wildcard characters in a LIKE pattern.

получается, что в condition по умолчанию используется оператор AND?

да

А если условие OR , тогда пользуемся db_or() ?

да

А зачем тогда нужно db_and() ?

чтобы использовать внутри db_or()

Андрей
31.01.2012, 22:31

Возможно вопрос немного не в тему.. но оч надо.. Насколько я знаю, в семерке база данных в INNDB , когда я портировал модуль из шестерки в семерку, импорт товаров вместо 5 сек длится 3 минуты. Почитал это http://www.sql.ru/forum/actualthread.aspx?tid=381637 и понял, что в базах INNDB, перед тем, как в цикле выполнять много запросов в базу их нужно сперва обьединить в транзакцию, а потом выполнить ее.. Иначе все жутко медленно..

Не подскажете, как сделать это? вот у ситуация например: нужно записать 1000 строк в базу. Я делаю так: форичем пробегаю по массиву строк, который нужно записать, и на каждом шаге делаю запрос инсерт в базу..

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

Пожалуйста, подскажите!

UPDATE t1, t2 SET t1.user = '145' WHERE ((t1.items=t2.id) and (t2.id=5))

корректен ли такой запрос?
И как он выглядит в drupal ?

db_query("UPDATE t1, t2 SET t1.user = '145' WHERE ((t1.items=t2.id) and (t2.id=5))");
Петров Николай
15.02.2012, 17:48

А как узнать ID последней строки записанной в базу с помощью этих методов?

Например я использую запрос:

db_insert('my_table')
->fields(array(
	'uid' => $user->uid,
	'nid' => $nid,
	'rid' => $rid,
	'text' => $text
))
->execute();

Классическое ПХП предлагает мне использовать mysql_insert_id(), но этой функции как я понял нужен идентификатор соединения с базой, а где его взять?

Либо может есть друпал-вей метод? я нашел только это, но не смог приспособить его к моему запросу: http://drupal.org/node/141926#comment-4536930

Петров Николай
15.02.2012, 18:05

Ого, как все оказалось просто! Спасибо :)

Гость
01.03.2012, 18:09

а как в запросе
$count = db_select('node')
->countQuery()
->execute()
->fetchField();

указать еще условие например $node->nid = 1

так же как в любом другом запросе - condition($field, $value, $operator)

Спасибо, с LIKE я бы еще долго дрочился...

Гость
26.03.2012, 12:44

а как составить что нить вроде этого:

select FROM_UNIXTIME(timestamp, '%Y%m%d') as ts, count(*) from `simpleads_clicks`
where (FROM_UNIXTIME(timestamp) <= NOW() AND FROM_UNIXTIME(timestamp) >= SUBDATE(NOW(), INTERVAL 1 MONTH) and nid = 45)
group by ts

Гость
26.03.2012, 13:44

угу спс... уэе разобрался, просто запостил сразу чтобы быстрее помогли, время мало))
вот что получилосб

$stats = db_select('simpleads_clicks', 'sc');
  $stats->addExpression("FROM_UNIXTIME(timestamp, '%Y/%m/%d')", 'ts');
  $stats->addExpression('COUNT(*)', 'count');
  $stats->where("FROM_UNIXTIME(sc.timestamp) <= NOW() AND FROM_UNIXTIME(sc.timestamp) >= SUBDATE(NOW(), INTERVAL 1 MONTH)");
  $stats->condition("sc.nid", 45);
  $stats->groupBy('ts');
  $count = $stats->execute()->fetchAll();
Виталий
29.03.2012, 13:44

Помогите пожалуйста. Делаю запрос как по документации, но результат шокирующий. Вот запрос:

$pid = "3,5";
$product_nids = db_query('SELECT entity_id
FROM {field_data_field_product} WHERE field_product_product_id IN (:pid)', array(':pid' => $pid));

foreach ($product_nids as $nid) {
var_dump($nid);
}

Но дело в том, что по циклу проходится только один раз, хотя обе записи присутствуют в БД. Что не так?

Виталий
29.03.2012, 13:59

Но я же делаю как в первом варианте. ПОчему он работает не правильно? Вариант 2 у меня выдает ошибку и скрипт прерывается на строке где execute()

в плейсхолдер надо передавать массив, а не строку

Доброе утро. Направьте вектор мыслей.
Создал таблицу по вот этому примеру.
Вывод таблицы сделал через Views.
1.Не хватает знаний сделать кнопки сортировок для каждого поля
2. Где можно почитать про создание сложных связанных бд с сущностями связками относительно Drupal?

не могу аонять как правильно использовать drupal_write_record. Как я понял она должна если записи имееться в бд обновлять если нету добавлять новую

таблица имеет следующую структуру

CREATE TABLE `node_type_redirect` (
	`ntrid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'The prinary identificator of redirect.',
	`type` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'The node_type of this node.',
	`path` VARCHAR(64) NULL DEFAULT '' COMMENT 'Redirect path',
	`status` INT(11) NULL DEFAULT '0' COMMENT 'Redirect path on/off',
	PRIMARY KEY (`ntrid`)
)

использую следующий код

	$record = array(
	  'type' => 'zzzzzzz',
	  'path' => '1113333',
	  'status' => 1,
	);
	$res = drupal_write_record('node_type_redirect', $record, 'type');

это код обновляет запись type если таковая имееться в таблице, если нету новую не добавляет.
следующий код

	$record = array(
	  'type' => 'zzzzzzz',
	  'path' => '1113333',
	  'status' => 1,
	);
	$res = drupal_write_record('node_type_redirect', $record);

добавляет запись в независимости имеется такая или нет.

как сделать чтобы если имеется запись поля type она обновлялась, если нету добавлялась новая?

Как я понял она должна если записи имееться в бд обновлять если нету добавлять новую

не правильно поняли

как сделать чтобы если имеется запись поля type она обновлялась, если нету добавлялась новая?

http://api.drupal.org/api/drupal/includes!database!database.inc/functio…

drupal 6.
допустим использую запрос

db_query("UPDATE {node} SET status = %d WHERE nid = %d", 1, 123);

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

Гость
17.07.2012, 20:03

подскажите как добавить оператор REGEXP в db_select()?

Гость
20.07.2012, 21:23

Чем заменить pager_query c Drupal 6 в Drupal 7 если запрос что бы не переписывать запрос в новую форму?
extend('PagerDefault') не работает с db_query.

Привет, а можно подробней объяснить про инкремент значений полей, у меня всплыла задача: нужно переопределить значение авто-инкримента для полей nid и vid например на 1000, потом все материалы пересейвить под новые ниды и виды (1000, 1001 ...), + конечно же не потерять все ривизии для нод, уже более полу дня не могу костыль сей реализовать..

Павел
23.10.2012, 12:58

Привет!
Есть такой запрос

SELECT DISTINCT left( name, 1 ) FROM postindex_street ORDER BY name

который возвращает первые буквы поля NAME убирая дубли.

Написал запрос для 7-ой версии

  $query = db_select('postindex_street', 'pstr')
    ->distinct()
    ->fields('pstr')
    ->orderBy('name', 'ASC');
  
  $query->AddExpression('left(name,1)', 'name');
    
  $result = $query->execute();

В итоге получаю результат с дублями, такое ощущение что ->distinct() не сработал.

Хотя если напишу запрос по старинке

$result = db_query('SELECT DISTINCT left( name, 1 ) 
                                   FROM postindex_street 
                                   ORDER BY name');

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

Может кто подсказать что с моим запросом под 7-ку нет?

Павел
23.10.2012, 13:30

Сам разобрался. Убрал ->fields('pstr') и все заработало.

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

	$where =& $query->conditions();
        unset($where); 

не работает. Как правильно?
Нашел пример для groupBy http://www.brenthartmann.com/blog/how-use-hookqueryalter-drupal-7
Но как сделать аналогично для where не понимаю

Если делаю

		$where = &$query->where();
		 unset($where); 

Получаю ошибку:

Warning: Missing argument 1 for SelectQueryExtender::where(), called in /usr/local/www/m500.by/sites/all/modules/mymodule/mymodule.module on line 33 and defined в функции SelectQueryExtender->where() (строка 626 в файле /usr/local/www/m500.by/includes/database/select.inc).
Notice: Undefined variable: snippet в функции SelectQueryExtender->where() (строка 627 в файле /usr/local/www/m500.by/includes/database/select.inc).
Strict warning: Only variables should be assigned by reference в функции mymodule_query_node_access_alter() (строка 33 в файле /usr/local/www/m500.by/sites/all/modules/mymodule/mymodule.module).
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ORDER BY t.sticky DESC, t.created DESC LIMIT 10 OFFSET 0' at line 1: SELECT t.nid AS nid, t.tid AS tid, t.sticky AS sticky, t.created AS created FROM {taxonomy_index} t WHERE (tid = :db_condition_placeholder_1) AND () ORDER BY t.sticky DESC, t.created DESC LIMIT 10 OFFSET 0; Array ( [:db_condition_placeholder_1] => 125 ) в функции PagerDefault->execute() (строка 79 в файле /usr/local/www/m500.by/includes/pager.inc).
Андрей
26.01.2013, 18:57

помогите , плиз. надо организовать элементарный запрос :

SELECT count(*) FROM affiliate_users_ids WHERE UCASE(text_id)=UCASE($Var)

вместо $Var надо подставить кое - что (в запросе ниже это txt). бьюсь весь день как организовать это на языке друпал . пытаюсь так :

db_select('affiliate_users_ids')
  ->countQuery()
  ->where('UCASE(text_id)=UCASE(:txt)', array(':txt' => $textid_primay_part . $textid_cnt . $textid_secondary_part))
  ->execute()
  ->fetchField()

но выдаёт ошибку :

PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'text_id' in 'where clause': SELECT COUNT(*) AS expression FROM (SELECT 1 AS expression FROM {affiliate_users_ids} affiliate_users_ids) subquery WHERE (UCASE(text_id)=UCASE(:txt)) ; Array ( [:txt] => OL1012613 ) в функции gaa_createUserTextID() (строка 14 в файле /usr/www/users/webmisq/drupal/sites/all/modules/gaa_user_sinhronaze/gaa_user_sinhronaze.module).

Гость
21.02.2013, 13:56

Прошу помощи необходимо выполнить запрос: выбрать записи, где значение поля 1 не равно значению поля 2 из одной таблицы, причем выполнение реализовано в общей массе , те пытался:
$query->condition( 'n.field1', 'n.field2', '!=');
но, естественно не работает ((

Александр
12.04.2013, 20:49

Добрый вечер!
У меня есть тип материала "категории" который представляет из себя обычный chekbox, как мне поучить все значения этого типа? Я хочу заполнить форму checkboxes. Чтобы мне не писать значения вручную я хочу сделать запрос.

У меня есть тип материала "категории"...

$nodes = db_select('node', 'n')
  ->fields('n', array('nid', 'title'))
  ->condition('n.type', 'categories')
  ->execute()->fetchAll();

debug($nodes);
Николай
30.04.2013, 15:39

Подскажите пожалуйста как вывести текущую дату плюс 2 дня: в блоке. Если вывожу date("d")+2 то получаю например 32 марта. Извините за нубовский вопрос php только начал изучать но я так понимаю это надо через запрос к бд делать?

Павел
03.05.2013, 22:10

Приветствую!
Можете подсказать как использовать функцию concat в select для объединения двух полей из разных таблиц?
Привожу пример для наглядности.

SELECT pa.code, concat( pr.name, ', ', pa.name ) , pa.postindex
FROM postindex_area pa
JOIN postindex_region pr ON pa.code_region = pr.code
Павел
10.05.2013, 14:30

to xandeadx: Спасибо за ответ.

Возник еще один вопрос. В JOIN мне надо сделать проверку с использованием строковой функции LEFT, например:

SELECT pa.code, concat( pr.name, ', ', pa.name ) , pa.postindex
FROM postindex_area pa
JOIN postindex_region pr ON LEFT(pa.code, 2) = pr.code)

Принимает ли функция join строковую функцию SQL в условиях проверки?

Я написал так, но что-то join не отрабатывает условие как надо:

  $query->Join('postindex_region', 'pr', 'LEFT(pa.code, 2) = pr.code');
Павел
10.05.2013, 22:38

Снимаю свой вопрос. Все работает.

Возникла необходимость фильтровать по полю varchar.

Но есть проблема: при генерации запроса друпал обрамляет значения в апострофы и это неправильно сказывается на результате.
Что делаю:

$query->add_where(0, 
 db_and()  
  ->condition($table3.".field_value_value", min($value), '>=')
  ->condition($table3.".field_value_value", max($value), '<=')
  ->condition($table6.".field_label_value", $label, '=')
);

Получаю:

WHERE ((( (field_data_field_value.field_value_value >= '14') AND (field_data_field_value.field_value_value <= '22') AND (field_data_field_label.field_label_value = 'Длина') )AND( (field_data_field_value_1.field_value_value >= '5') AND (field_data_field_value_1.field_value_value <= '13') AND (field_data_field_label_1.field_label_value = 'Диаметр')...

Как заставить друпал генерировать запрос без кавычек в значениях. Иначе результат получается неверным.

Добавить комментарий