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
08/05/2020, by maria

Запросы на вставку всегда должны использовать объект построителя запросов. В некоторых базах данных требуется специальная обработка полей LOB (Large OBject, например TEXT в MySQL) и BLOB (Binary Large OBject), поэтому требуется уровень абстракции, чтобы отдельные драйверы баз данных могли реализовать любую специальную обработку, которая им требуется.

Запросы на вставку запускаются с использованием метода insert() следующим образом:

$query = $connection->insert('mytable', $options);

Это создает объект запроса вставки, который вставит одну или несколько записей в таблицу mytable. Обратите внимание, что фигурные скобки не требуются для имени таблицы, поскольку построитель запросов будет обрабатывать это автоматически.

Объект запроса вставки использует свободный API. То есть все методы (кроме execute()) возвращают сам объект запроса, позволяя объединять вызовы методов. Во многих случаях это означает, что объект запроса вообще не нужно сохранять в переменную.

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

Компактная форма

Предпочтительной формой для большинства запросов на вставку является компактная форма:

$result = $connection->insert('mytable')
  ->fields([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])
  ->execute();

Это приведет к эквиваленту следующего запроса:

INSERT INTO {mytable} (title, uid, created) VALUES ('Example', 1, 1221717405);

Вышеуказанный фрагмент объединяет ключевые части процесса вставки.

$connection->insert('mytable')

Эта строка создает новый объект запроса вставки для таблицы mytable.

  ->fields([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])

Метод fields() принимает несколько форм параметров, но наиболее часто используется один ассоциативный массив. Ключами массива являются столбцы таблицы, в которые нужно вставить, а значения - соответствующие значения для вставки. Это приведет к одному запросу на вставку к указанной таблице.

 ->execute();

Метод execute() сообщает запросу на выполнение. Если этот метод не вызван, запрос не выполняется.

В отличие от других методов объекта запроса Вставка, которые возвращают сам объект запроса, execute() возвращает значение поля автоинкремента (последовательный тип в hook_schema()), которое было заполнено запросом Вставки, если таковые имеются. Вот почему возвращаемое значение из него присваивается $result в примере выше. Если поле автоинкремента отсутствует, возвращаемое значение execute() не определено и ему нельзя доверять.

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

Degenerate form

$result = $connection->insert('mytable')
  ->fields(['title', 'uid', 'created'])
  ->values([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])
  ->execute();

Это несколько более подробный эквивалент предыдущего запроса и будет иметь точно такой же результат.

  ->fields(['title', 'uid', 'created'])

Когда fields() вызывается с индексированным массивом вместо ассоциативного массива, он устанавливает только те поля (столбцы базы данных), которые будут использоваться в запросе, без установки каких-либо значений для них. Это полезно для запуска многостраничного запроса позже.

  ->values([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])

Этот вызов метода задает ассоциативный массив имен полей для значений, которые нужно вставить в эти поля. Метод values() может также взять индексированный массив. Если используется индексированный массив, порядок значений должен соответствовать порядку полей в методе fields(). Если используется ассоциативный массив, он может быть в любом порядке. Обычно ассоциативный массив предпочтителен для удобства чтения.

Эта форма запроса используется редко, так как предпочтительна компактная форма. В большинстве случаев единственной причиной для разделения fields() и values() является выполнение многостраничного запроса.

Форма с несколькими вставками

Объект запроса Вставка также может принимать несколько наборов значений. То есть values() может вызываться несколько раз, чтобы поставить в очередь несколько операторов вставки. Как именно это произойдет, будет зависеть от возможностей рассматриваемой базы данных. В большинстве баз данных несколько операторов вставки будут выполняться вместе внутри транзакции для большей целостности данных и скорости. В MySQL он будет использовать многозначный синтаксис вставки MySQL.

$values = [
  [
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ],
  [
    'title' => 'Example 2',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ],
  [
    'title' => 'Example 3',
    'uid' => 2,
    'created' => \Drupal::time()->getRequestTime(),
  ],
];
$query = $connection->insert('mytable')->fields(['title', 'uid', 'created']);
foreach ($values as $record) {
  $query->values($record);
}
$query->execute();

В приведенном выше примере три оператора вставки будут выполняться вместе как единое целое, используя наиболее эффективный метод для конкретного используемого драйвера базы данных. Обратите внимание, что здесь мы сохранили объект запроса в переменной, чтобы мы могли циклически обращаться к $values ​​и повторно вызывать метод values​​().

В вырожденном случае приведенный выше пример эквивалентен следующим трем запросам:

INSERT INTO {mytable} (title, uid, created) VALUES ('Example', 1, 1221717405);
INSERT INTO {mytable} (title, uid, created) VALUES ('Example2', 1, 1221717405);
INSERT INTO {mytable} (title, uid, created) VALUES ('Example3', 2, 1221717405);

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

Вставка по результатам запроса select

Если вы хотите заполнить таблицу результатами из других таблиц, вам нужно либо выбрать SELECT из исходных таблиц, перебрать данные в PHP и вставить их в новую таблицу, либо выполнить запрос INSERT INTO ... SELECT FROM в которой каждая запись, возвращаемая из запроса SELECT, подается в запрос INSERT.

В этом примере мы хотим построить таблицу mytable, в которой есть nid и имя пользователя для всех узлов в системе, которые имеют тип page.

<?php
// Build the SELECT query.
$query = $connection->select('node', 'n');
// Join to the users table.
$query->join('users', 'u', 'n.uid = u.uid');
// Add the fields we want.
$query->addField('n','nid');
$query->addField('u','name');
// Add a condition to only get page nodes.
$query->condition('type', 'page');

// Perform the insert.
$connection->insert('mytable')
  ->from($query)
  ->execute();
?>

Значения по умолчанию

В нормальных условиях, если вы не укажете значение для данного поля и значение по умолчанию определено схемой таблицы, тогда база данных автоматически вставит это значение по умолчанию для вас. Однако в некоторых случаях вам необходимо явно указать базе данных использовать значение по умолчанию. Это включает в себя, если вы хотите использовать все значения по умолчанию для всей записи. Чтобы явно указать базе данных использовать значение по умолчанию для данного поля, существует метод useDefaults().

$query->useDefaults(['field1', 'field2']);

Эта строка указывает запросу использовать заданные по умолчанию значения по умолчанию для полей field1 и field2. Обратите внимание, что указание одного и того же поля в useDefaults() и fields() или values() является ошибкой, и будет выдано исключение.

$connection->insert() or $connection->query()

Это часто задаваемый вопрос. (См. Комментарии на этой странице.) В чем разница между insert() и query()?

В методе insert() каждый столбец указывается как отдельная запись в массиве полей, и код может очищать значение каждого столбца. У query() есть строка SQL без возможности проверки отдельных столбцов. Если вы используете query() с местозаполнителями, код может проверять значения столбцов, но заполнители - это всего лишь опция, и нет способа гарантировать, что ваш SQL не содержит значений, не пропущенных через заполнители.

insert() пропускает запрос через набор хуков, чтобы позволить другим модулям проверять и изменять ваши запросы. Это правильный способ работы с другими модулями. query() немного быстрее, потому что query() не передает запрос через хуки. Вы можете сэкономить время обработки, но ваш код не позволит другим модулям помочь вашему коду.

insert() чаще работает с другими базами данных и будущими версиями Drupal.

Source URL:

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.