УрокCоздание и обновление записей в базе данных через Drupal API

В большинстве модулей записи в базу данных делаются постоянно - будь то новые записи, или же обновление уже существующих. Друпал позволяет выполнять прямые запросы в базу через db_query.

Вставка записи:

db_query('INSERT INTO {mytable} (value1, value2) VALUES  (%d, "%s")', $int, $string);

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

db_query('UPDATE {mytable} SET value2 = "%s" WHERE value1 = %d', $new_string, $int);

Однако хорошим тоном является использование функции из Drupal API drupal_write_record.

Вставка записи:

$row = new stdClass();
$row->value1 = $int;
$row->value2 = $string;
drupal_write_record('mytable', $row);

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

$row = new stdClass();
$row->value1 = $int;
$row->value2 = $string;
drupal_write_record('mytable', $row, 'value1');

Преимущества drupal_write_record:

  • От глаз скрыты прямые запросы в базу данных
  • Выполняет за вас предварительную работу с данными (сериализация, приведение типов и т.д.)
  • Позволяет сэкономить время на написании своего запроса
  • Уберегает от возможных ошибок в запросе

Недостатки:

  • Невозможно при апдейте записать значением поля NULL
  • Не работает при включении и установке модуля (hook_install, hook_enable) без дополнительного кода перед вызовом функции
  • Не работает с таблицами, не описанными в hook_schema

Обновление и запись в базу данных Drupal 7

Всё вышесказанное действительно и для седьмого Друпала. Однако с его выходом появился более гибкий механизм записи/обновления таблиц - db_merge(). Она знает, что надо делать с записью - вставлять или обновлять, поэтому её использование является максимально удобным. И пример для наглядности:

Запись данных в таблицу без использования db_merge:

function example_insert($name, $value1, $value2) {
  $row_exists = db_query(
    'SELECT field1 FROM {example} WHERE name = :name', 
    array(':name' => $name)
  )->fetchField();
  if ($row_exists) {
    db_query(
      'UPDATE {example} SET field1 = :value1, field2 = :value2 WHERE name = :name', 
      array(':name' => $name, ':value1' => $value1, ':value2' => $value2)
    );
  }
  else {
    db_query(
      'INSERT INTO {example} (name, field1, field2) VALUES (:name, :value1, :value2)', 
      array(':name' => $name, ':value1' => $value1, ':value2' => $value2)
    );
  }
}

С использованием db_merge:

function example_insert($name, $value1, $value2) {
  db_merge('example')
    ->key(array('name' => $name))
    ->fields(array(
        'field1' => $value1,
        'field2' => $value2,
    ))
    ->execute();
}

Разница, я думаю, очевидна ;)

Комментарии

Аватар пользователя xandeadx
xandeadx написал:

в подавляющем большинстве запросов, :name это суррогатный ключ (primary key с auto increment) и его значение не известно до инсерта. так что db_merge не в кассу

21.11.2011 09:18
Аватар пользователя Spleshka
Spleshka написал:

Совсем не в большинстве. Максимум в половине случаев, вряд ли больше. Поэтому для остальных случаев db_merge очень даже удобен.

21.11.2011 12:56
Аватар пользователя xandeadx
xandeadx написал:

хочешь сказать половина таблиц в d7 не имеют суррогатных ключей?) открой бд ради интереса ;)

21.11.2011 16:29
Аватар пользователя Spleshka
Spleshka написал:

а ты хочешь сказать что db_merge() бесполезная функция ?) Открыл бд в 7ке - да, больше половины таблиц имеют суррогатные ключи. Но это же не делает функцию бесполезной. В некоторых ситуациях она может уменьшить количество кода и ускорить разработку. Я же не писал, что её надо пихать куда только можно ;)

21.11.2011 20:03
Аватар пользователя Гость
Гость написал:

не говорил что бесполезная

Я же не писал, что её надо пихать куда только можно

слова "более гибкий механизм записи/обновления таблиц - db_merge()" я истрактовал именно так ;)

21.11.2011 20:32
Аватар пользователя Spleshka
Spleshka написал:

Ну определённое преимущество перед drupal_write_record() у неё в любом случае есть, тут ведь не поспоришь :)

21.11.2011 20:41
Аватар пользователя имя
имя написал:
<ol>
 <li><ul>
 <li><h3><div class="editor-right-button"><div class="editor-center-button"><div class="editor-left-button"><strike><u><em><strong></strong></em></u></strike>
</div></div></div></h3></li>
</ul></li>
</ol>
05.01.2016 18:49

Комментировать