it-swarm-es.com

db_affected_rows en Drupal 7 para db_query

Me acabo de dar cuenta de que @ Berdir fue tan agradable de eliminar db_affected_rows de Drupal 7 . Ahora me pregunto cuál es la mejor práctica para detectar si la consulta que ejecutó cambió algo en la base de datos.

Un caso de uso típico sería.

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

Eché un vistazo al objeto de consulta devuelto por db_query, pero no me pareció de mucha ayuda.

Actualización:
Veo que no estaba claro en qué circunstancias necesitaba la información.

Mi caso de uso actual es bastante simple. Tengo una tabla para un tipo de nodo con una columna nid y algunas columnas de datos. Tengo un formulario y al enviar el formulario, quiero insertar o actualizar la fila en la base de datos.

El problema con db_update/db_insert es que, si uso la actualización primero, y la inserto si la actualización devuelve 0, no captaré la condición, donde el formulario se envió con el valor en la base de datos. Si uso db_insert primero, eso generará un error si ya hay una fila en la base de datos.

Supongo que en esta condición específica podría insertar un valor en blanco cuando se crea el nodo y luego solo usar la actualización, pero en algunos casos eso podría no ser posible, si necesito almacenar información que fue ingresada en una base de datos externa. También me gustaría evitar tener que depender de los valores de la base de datos para que mi código funcione.

Mi estrategia habitual para tales casos ha sido hacer un

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

Hacer esto es simple y sin errores, sin importar en qué condición se encuentre la base de datos. La mejor opción que puedo ver en este momento sería manejarlo con SQL y hacer esto:

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

Pero esperaba que la API de db pudiera manejar esto.

8
googletorp

Después de investigar, descubrí que Drupal proporciona una herramienta lista para mi caso de uso exacto:

Inserte una fila en la base de datos o actualice la existente si ya está allí.

Esto se llama fusionar consultas , que se puede hacer atómicamente para algunos motores db.

El syntext es bastante simple:

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

Esa información es devuelta directamente por el método execute () de Delete/UpdateQuery, vea por ejemplo: pdateQuery :: execute () .

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

Y InsertQuery :: execute () devuelve la última identificación de inserción.

9
Berdir