如何将值数组保存在数据库中?


8

我试图将多个值从textarea保存到数据库表。

我使用以下代码,但我认为这是错误的方法。

foreach ($user_emails as $key => $value) {
  $insert_banned_emails = db_insert('banned_users');
  $insert_banned_emails
    ->fields(array(
      'email' => $value,
    ))
    ->execute();
}

有没有其他方法可以达到相同的结果?

Answers:


15

我将使用以下代码。

foreach ($user_emails as $value) {
  $query = db_insert('banned_users');
  $query->fields(array('email' => $value))->execute();
}

另外,您可以使用以下代码。

$query = db_insert('banned_users')->fields(array('email'));

foreach ($user_emails as $value) {
  $query->values(array('email' => $value));
}

$query->execute();

在MySQL中,查询使用多值语法。

对于其他数据库,对于$query->values()包装在事务中的对的每次调用,将执行一个查询。这意味着当其中一个查询失败时,查询将回滚。实际上,从InsertQuery :: execute()执行的代码如下。

  // Each insert happens in its own query in the degenerate case. However,
  // we wrap it in a transaction so that it is atomic where possible. On many
  // databases, such as SQLite, this is also a notable performance boost.
  $transaction = $this->connection->startTransaction();

  try {
    $sql = (string) $this;
    foreach ($this->insertValues as $insert_values) {
      $last_insert_id = $this->connection->query($sql, $insert_values, $this->queryOptions);
    }
  }
  catch (Exception $e) {
    // One of the INSERTs failed, rollback the whole batch.
    $transaction->rollback();
    // Rethrow the exception for the calling code.
    throw $e;
  }

简而言之,如果插入的值彼此独立,那么我将使用您正在使用的代码。当值相互依赖时,我将使用显示的代码。

就您而言,电子邮件彼此独立。如果要使用我显示的第二个代码段,则在子查询不失败时,数据库表将包含所有值;在单个子查询失败时,数据库表将包含所有值。

drupal_write_record()即使我更喜欢其他片段,也可以使用。

foreach ($user_emails as $value) {
  drupal_write_record('banned_users', array('email' => $value));
}

不过,我看不到使用此代码段的任何专业人士。

参考


1
很抱歉,此文档页面上显示的“多插入表格”如何处理。给出1的数组,$values仅调用1 execute()drupal.org/node/310079例如,在标准配置文件默认块创建中使用它。
tenken 2012年

2
“是的,您可以在上调用任意->values(...)InsertQuery,它会准备一个查询,例如INSERT INTO x (field1, field2) VALUES ('val1', 'val2'), ('val3', 'val4'), etc
Clive

2
好了,现在我想起了为什么放弃使用$query->values():在我的大多数情况下,我的代码插入的值彼此独立,并且我不希望值错误导致其他值回滚。
kiamlaluno

3

这是与您的代码相似的版本,但性能更高。您确实不想调用execute()一千次,只需要调用一次即可。

参考

$insert_banned_emails = db_insert('banned_users')->fields(array('email'));
foreach ($user_emails as $key => $value) {
  $insert_banned_emails->values(array(
    'email' => $value,
  ));               
}
$insert_banned_emails->execute();

为我工作,除了在我的情况下行数太大(10,000)时会引发OOM错误。因此,我将其分为1000个或更少的批次来解决该问题。
Eduardo Chongkan,2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.