DQL Update NULL avec Doctrine

Pour mettre à jour une valeur qui peut être nulle ou peut contenir une valeur valide non nulle, il vous faut faire un if ternaire : condition ? true : false

->set('leChamp', (($laValeur=== null) ? 'NULL' : '?'), $laValeur)

ou coder le if

  • pour le null
->set('leChamp', 'NULL');
  • pour la valeur (non nulle)
->set('leChamp', '?', $laValeur);

Mais ne surtout pas faire :

$laValeur = null;
 ->set('leChamp', '?', $laValeur);

équivalent à

->set('leChamp', '?', null);

car cela provoque l'erreur suivante : Fatal error: Uncaught exception 'Doctrine_Connection_Mysql_Exception' with message 'SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens'

DQL Update fails with passed NULL value (closed defect: invalid)
When you want to set null values, you have to use the second argument.
->set('f.bar', 'NULL');
Let's imagine a real life situation. If may be NULL or a valid value... so your code will be something like:
->set('f.bar', (($value === null) ? 'NULL' : '?'), $value)

Utilisation basique de Doctrine

Select Doctrine

$users = Doctrine::getTable('User')->findAll();
  foreach($users as $user) {
   echo $user->name;
  }

Insert Doctrine

$user = new User();
 $user->name = "marie";
 $user->password = "xxx";
 $user->save();
 
 echo "L'utilisateur avec l'id $user->id a été ajouté";

Update Doctrine

$user = Doctrine::getTable('User')->findBy(2);
  $user->phone = "09 22 22 22";
  $user->save();

Delete Doctrine

$user = Doctrine::getTable('User')->findByName("marie");
  $user->delete();

Replace Doctrine

$veloce = new Veloce();
  $veloce->id = $id;
  $veloce->veloce = $veloce;
  $veloce->quantite = $nbr;
  $veloce->replace();

SQL DQL Doctrine

$stmt_update = Doctrine_Query::create()
->update('Matable matable')
->set('matable.etat', '?', $monEtat)
->set('matable.date_isdo', 'CURRENT_TIMESTAMP')
->execute();
// mais impossible de construite un IF MYSQL par exemple

Avec Doctrine 1.2, il est impossible de construire un IF tel que :

UPDATE matable
SET matable.etat = IF(matable.etat=0, 128, matable.etat)

Pour les "Control Flow Functions" en Doctrine 1.2, il n'existe pas en pas natif, ni même dans les extensions Doctrine natives. Pour Doctrine 2.x, l'extension existe :

Les "Magic Finders"

Les patterns de base pour les méthodes de recherche (Magic Finders) sont les suivants : findBy%s($valeur) ou findOneBy%s($valeur). Le %s peut être un nom de colonne ou un alias de relation.

// Recherche par la clé primaire : $tableClass->find($primaryKey);
$user = $userTable->find(1);
// Recherche par champs : (username) : $tableClass>findOneByUsername($searchInput);
$userTable->findOneByUsername('jonwage');
// En combinant les critères de recherche : 
$user = $userTable->findOneByUsernameAndPassword('jonwage', md5('changeme'));
$users = $userTable->findByIsAdminAndIsModeratorOrIsSuperAdmin(true, true, true);

Les expression NOW(), CURRENT_TIMESTAMP()

Using Expression Values

$user = new User();
$user->username = 'placeoweb';
$user->updated_at = new Doctrine_Expression('NOW()');
$user->save();
$stmt = Doctrine_Query::create()
	->select('COUNT(*) AS existe')
	->from('DefVeloce dv')
	->andWhere('dv.veloce = ?',$veloce)
//	->andWhere('date_fin_validite > ?', Doctrine_Expression_Driver::now());	// ko quotes
//	->andWhere('date_fin_validite >= ?', new Doctrine_Expression('NOW()'));	// ko quotes
//	->andWhere('date_fin_validite > ' . new Doctrine_Expression('NOW()'));	// ok
	->andWhere('date_fin_validite > CURRENT_TIMESTAMP');	// ok
	;
	//->groupBy('dv.veloce');
	$row = $stmt->fetchOne();

Ressources

Les versions de Doctrine 1.2.x

  • Doctrine 1.2.4 2011-03-21
  • Doctrine 1.2.3 2010-08-24
  • Doctrine 1.2.2 2010-03-29
  • Doctrine 1.2.1 2009-12-07