Урок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(); }
Разница, я думаю, очевидна ;)
- Spleshka
- 20.11.2011
- 21884
Комментарии
в подавляющем большинстве запросов, :name это суррогатный ключ (primary key с auto increment) и его значение не известно до инсерта. так что db_merge не в кассу
Совсем не в большинстве. Максимум в половине случаев, вряд ли больше. Поэтому для остальных случаев db_merge очень даже удобен.
хочешь сказать половина таблиц в d7 не имеют суррогатных ключей?) открой бд ради интереса ;)
а ты хочешь сказать что db_merge() бесполезная функция ?) Открыл бд в 7ке - да, больше половины таблиц имеют суррогатные ключи. Но это же не делает функцию бесполезной. В некоторых ситуациях она может уменьшить количество кода и ускорить разработку. Я же не писал, что её надо пихать куда только можно ;)
не говорил что бесполезная
Я же не писал, что её надо пихать куда только можно
слова "более гибкий механизм записи/обновления таблиц - db_merge()" я истрактовал именно так ;)
Ну определённое преимущество перед drupal_write_record() у неё в любом случае есть, тут ведь не поспоришь :)
Комментировать