db_affected_rows di Drupal 7 untuk db_query


8

Saya hanya memperhatikan bahwa @Berdir sangat baik untuk dihapus db_affected_rowsdari Drupal 7 . Saya sekarang bertanya-tanya apa praktik terbaik sekarang untuk mendeteksi jika kueri yang Anda jalankan mengubah apa pun dalam database.

Sebuah usecase khas akan menjadi.

db_query(...);
if (!db_affected_rows()) {
  db_query(...);
}

Saya melihat objek permintaan yang dikembalikan dari db_query, tapi sepertinya tidak banyak membantu.

Pembaruan:
Saya melihat saya agak tidak jelas tentang keadaan apa saya membutuhkan info.

Kasus penggunaan saya saat ini, adalah kasus yang cukup sederhana. Saya punya tabel untuk tipe simpul dengan kolom nid dan beberapa kolom data. Saya memiliki formulir saat mengirimkan formulir, saya ingin memasukkan atau memperbarui baris dalam db.

Masalahnya dengan db_update/ db_insertadalah bahwa, jika saya menggunakan pembaruan terlebih dahulu, dan menyisipkan jika pembaruan mengembalikan 0, saya tidak akan mengetahui kondisinya, di mana formulir dikirimkan dengan nilai dalam db. Jika saya menggunakan db_insert terlebih dahulu, itu akan meningkatkan en error jika sudah ada baris di db.

Saya kira saya dalam kondisi khusus ini dapat menyisipkan nilai kosong ketika node dibuat dan kemudian hanya menggunakan pembaruan, tetapi untuk beberapa kasus itu mungkin tidak mungkin, jika saya perlu menyimpan info yang dikunci ke database eksternal. Saya juga ingin menghindari ketergantungan pada nilai basis data agar kode saya berfungsi.

Strategi saya yang biasa untuk kasus seperti itu, adalah melakukan a

db_query("INSERT IGNORE INTO ...")
if (!db_affected_rows()) {
  db_query("UPDATE ...");
}

Melakukan ini sederhana dan bebas kesalahan, tidak peduli dalam kondisi apa db berada. Opsi terbaik yang dapat saya lihat sekarang, adalah menanganinya dengan SQL dan melakukan ini:

db_query("INSERT ... ON DUPLICATE KEY UPDATE");

Tapi saya berharap bahwa API db akan mampu menangani ini.

Jawaban:


9

Informasi itu langsung dikembalikan oleh metode execute () pada Delete / UpdateQuery, lihat misalnya: UpdateQuery :: execute () .

<?php
$affected = db_update('some_table')
  ->fields(array(
    'some_field' => $value,
  ))
  ->condition('another_field', $id)
  ->execute();
?>

Dan InsertQuery :: execute () mengembalikan id insert terakhir.


8

Setelah menggali sekitar, saya menemukan bahwa Drupal memasok alat bernama siap untuk kasus penggunaan yang tepat saya:

Masukkan baris di db, atau perbarui yang sudah ada jika sudah ada.

Ini disebut permintaan gabungan , yang dapat dilakukan secara atomis untuk beberapa mesin db.

Sintaksnya cukup sederhana:

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

Ah ya, itu adalah jawaban yang benar untuk pertanyaan Anda yang diperbarui :) Perhatikan bahwa penggabungan kueri telah dirancang ulang pada akhir siklus pengembangan D7 untuk benar-benar berfungsi seperti kueri sql MERGE, yang merupakan bagian dari standar SQL 2003 tetapi tidak ada dbms yang benar-benar mengimplementasikannya. , jadi semua dbms memerlukan dua kueri (mereka dibuat atom dengan menggunakan transaksi). Masalah dengan pendekatan permintaan tunggal yang digunakan untuk MySQL adalah sepenuhnya mengabaikan definisi kunci () dan hanya bekerja dengan kunci unik / utama dari tabel yang diberikan.
Berdir

@Berdir: Terima kasih telah menunjukkan saya ke arah yang benar. Saya salah satu pengembang yang suka menulis SQL dan kesulitan membiasakan diri dengan API db baru :)
googletorp

Terima kasih atas penunjuk ini. Namun, saya harus menggunakan db_query karena api Drupal db tidak memungkinkan menggunakan konstanta seperti CURRENT_TIMESTAMP (lihat drupal.org/node/215821 )
Whiskey
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.