Bagaimana saya bisa menyimpan array nilai dalam database?


8

Saya mencoba untuk menyimpan beberapa nilai dari textarea ke tabel database.

Saya menggunakan kode berikut, tetapi saya merasa itu adalah cara yang salah.

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

Apakah ada cara berbeda untuk mencapai hasil yang sama?

Jawaban:


15

Saya akan menggunakan kode berikut.

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

Atau, Anda dapat menggunakan kode berikut.

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

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

$query->execute();

Dengan MySQL, kueri menggunakan sintaks multi-nilai.

Dengan basis data lain, kueri yang dieksekusi akan menjadi satu untuk setiap panggilan $query->values(), dibungkus dengan transaksi. Ini berarti pertanyaan akan dibatalkan ketika salah satu dari mereka gagal. Bahkan, kode yang dieksekusi dari InsertQuery :: execute () adalah yang berikut.

  // 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;
  }

Singkatnya, saya akan menggunakan kode yang Anda gunakan jika nilai yang dimasukkan independen satu sama lain; Saya akan menggunakan kode yang saya tunjukkan ketika nilainya tergantung satu sama lain.

Dalam kasus Anda, email-email itu independen satu sama lain. Jika Anda akan menggunakan potongan kedua yang saya perlihatkan, tabel database akan berisi semua nilai, ketika sub-kueri tidak gagal, atau tidak ada ketika satu sub-kueri gagal.

Anda juga bisa menggunakan drupal_write_record(), meskipun saya lebih suka potongan lainnya.

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

Saya tidak melihat pro dalam menggunakan cuplikan ini.

Referensi


1
Saya minta maaf bagaimana dengan "Formulir Multi-Sisipkan" yang ditunjukkan pada halaman dokumentasi ini. Berikan 1 array $valuesdan hanya panggil 1 execute(). drupal.org/node/310079 Ini digunakan misalnya dalam pembuatan blok standar profil standar.
Tenken

2
'Benar, Anda dapat menelepon ->values(...)sebanyak yang Anda inginkan pada InsertQuerydan itu akan menyiapkan pertanyaan sepertiINSERT INTO x (field1, field2) VALUES ('val1', 'val2'), ('val3', 'val4'), etc
Clive

2
Baiklah, sekarang saya ingat mengapa saya dibuang menggunakan $query->values(): Dalam sebagian besar kasus saya, nilai-nilai yang dimasukkan oleh kode saya independen satu sama lain, dan saya tidak ingin kesalahan dengan nilai menyebabkan kemunduran nilai-nilai lainnya.
kiamlaluno

3

Ini adalah versi yang mirip dengan kode Anda, tetapi kinerjanya lebih baik. Anda benar-benar tidak ingin memanggil execute () ribuan kali, Anda hanya perlu memanggilnya sekali.

Referensi

$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();

Bekerja untuk saya kecuali bahwa itu akan menimbulkan kesalahan OOM ketika jumlah baris terlalu besar (10.000) dalam kasus saya. Jadi saya membaginya menjadi batch 1000 atau kurang untuk menyelesaikan masalah itu.
Eduardo Chongkan
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.