web-dev-qa-db-fra.com

\ Drupal :: database () -> insert - Erreur: appel à une méthode non définie en utilisant -> condition ()?

J'essaie d'insérer une nouvelle ligne en fonction des conditions. La ->condition() dans $database->update() fonctionne bien, dans $database->insert() ce n'est pas le cas.

$database = \Drupal::database();

// Query our DB.
$queryDB = $database
  ->select('table_name', 'value3')
  ->fields('value3')
  ->condition('value1', $value1, "=")
  ->condition('value2', $value2, "=")
  ->execute()->fetchAll();

if (isset($queryDB[0])) {
  // Check if table row exists and overwrite.
  if ($queryDB[0]->value1 == $value1 && $queryDB[0]->value2 == $value2) {
    $database
      ->update('table_name')
      ->fields([
        'value3' => $value3,
      ])
      ->condition('value1', $value1, '=')
      ->condition('value2', $value2, '=')
      ->execute();
  }
}
// Create table row.
else {
  $database
    ->insert('table_name')
    ->fields([
      'value1' => $value1,
      'value2' => $value2,
      'value3' => $value3,
    ])
    // Without these conditions, I get a duplicate entry integrity restraint as value1 and/or value2 may already exist.
    // With them I get Error: Call to undefined method Drupal\Core\Database\Driver\mysql\Insert::condition().
    ->condition('value1', $value1, '!=')
    ->condition('value2', $value2, '!=')
    ->execute();
}

Questions très similaires: 1. la condition EntityQuery "n'est pas égale à ..." 2. Comment ajouter une condition à une requête?

Mais je n'ai pas de chance. Est-ce différent avec un insert?

Ce que je veux, c'est que si valeur1 ET valeur2 ne correspondent pas, créez une ligne de table entièrement nouvelle avec les trois valeurs.

3
Prestosaurus

Comme décrit dans Insert Queries , l'objet renvoyé par \Drupal::database()->insert() n'a pas de méthode condition(). Si le but du code est de créer une nouvelle ligne de base de données si elle n'existe pas ou de la mettre à jour si elle existe déjà, le code doit utiliser l'objet renvoyé par \Drupal::database()->merge(). Voir Fusionner les requêtes .

Par exemple, le code suivant créera une nouvelle ligne si aucune des lignes existantes ne contient la valeur $name Pour la colonne de base de données name; sinon, il mettra à jour la ligne correspondante existante. ($connection Est l'objet renvoyé par \Drupal::database() ou un objet Connection obtenu via l'injection de dépendances.)

$connection->merge('example')
  ->key(['name' => $name])
  ->fields([
      'field1' => $value1,
      'field2' => $value2,
  ])
  ->execute();

Il est également possible d'utiliser un ensemble de valeurs lorsque la ligne est créée et un autre ensemble lorsque la ligne est mise à jour.

$connection->merge('example')
  ->insertFields([
      'field1' => $value1,
      'field2' => $value2,
  ])
  ->updateFields([
    'field1' => $alternate1,
  ])
  ->key(['name' => $name])
  ->execute();

Ce que cette page de documentation ne montre pas, c'est comment utiliser plusieurs clés, comme le code suivant, en utilisant Merge::keys() au lieu de Merge::key() .

$connection->merge('example')
  ->insertFields([
      'field1' => $value1,
      'field2' => $value2,
  ])
  ->updateFields([
    'field1' => $alternate1,
  ])
  ->keys(['name' => $name, 'nickname' => $nickname])
  ->execute();

La seule limitation est que les valeurs passées à keys() sont toutes utilisées pour correspondre à une seule ligne de base de données. En d'autres termes, le dernier extrait que j'ai montré ne recherche pas une ligne contenant $name Dans la colonne de base de données name ou une ligne contenant $nickname dans la colonne nickname.

Dans les cas plus complexes, où la classe Merge n'aide pas, vous devez d'abord vérifier ce que contient la table de base de données et prendre les mesures nécessaires en vous basant sur le contenu de la table (ce qui implique d'écrire plus PHP code pour vérifier le contenu de la base de données).

5
kiamlaluno

Oui, c'est différent. Une instruction SQL INSERT n'a pas de clause WHERE, donc la méthode condition() mentionnée l n'existe pas pour la insert object .

Vous pouvez ajouter votre vérification conditionnelle dans PHP (par exemple $queryDB[0]->value1 != $value1) comme vous l'avez fait de manière redondante pour votre requête UPDATE.

2
Shawn Conn