Décrémenter la valeur au lieu de la définir comme `number = number - 1`. Est-ce possible à Magento?

8

J'ai besoin de décrémenter une valeur avec une opération de base de données atomique , est-il possible d'utiliser des modèles Magento?

setNumber($number)fonctionne comme number = $number, mais j'ai besoin qu'il soit décrémenté dans la requête SQL.

Est-il possible dans Magento ou dois-je écrire la requête SQL moi-même?

tmm
la source
4
Je vote pour fermer cette question comme hors sujet car elle concerne MYSQL
Sander Mangel
2
@ Sander-MageStackDay2015 Il ne s'agit pas de MYSQL, je demande s'il y a une fonction Magento qui au lieu d' setNumber(number)avoir quelque chose commedecreaseBy(number)
tmm

Réponses:

16

Oui, c'est possible en utilisant Zend_Db_Expr:

$object->setNumber(new Zend_Db_Expr('number-1'));

Pour référence:

La méthode Mage_Core_Model_Resource_Abstract::_prepareDataForSave()contient le code suivant:

if ($object->hasData($field)) {
    $fieldValue = $object->getData($field);
    if ($fieldValue instanceof Zend_Db_Expr) {
        $data[$field] = $fieldValue;
    } else {
        ... [normal value processing follows]

Modèles EAV:

Notez que vous ne pouvez référencer l'attribut que par son nom ("numéro" dans l'exemple) si c'est une vraie colonne de la table principale, pas un attribut EAV.

Bien que la méthode susmentionnée ne soit utilisée que par les modèles avec des tables plates, elle Zend_Db_Exprpeut également être utilisée pour les attributs EAV, la méthode qui la gère Varien_Db_Adapter_Pdo_Mysql::prepareColumnValue().

MAIS vous devez toujours utiliser le nom de colonne " value":

$product->setNumber(new Zend_Db_Expr('value-1'));

Vous n'avez pas besoin de spécifier un alias de table car lors de l'enregistrement, chaque attribut est traité avec sa propre requête, donc "valeur" n'est pas ambiguë.

Fabian Schmengler
la source
/ moi verse une larme ...
benmarks
1
Ce sont des larmes de joie. Très bonne réponse.
benmarks
Et comment faire cela avec une collection? :)
philwinkle
Il n'y a aucun moyen direct d'enregistrer des attributs dans une collection à la fois, mais vous pouvez probablement faire des trucs intelligents avec$collection->getSelect()
Fabian Schmengler
0
try ->setNumber(getNumber() - $number)

Edit: Ce serait équivalent à Set number = number - Xdans mysql où X est $ nombre.

Si vous voulez le faire uniquement dans MySQL, il vous suffit d'écrire une requête.

Paras Sood
la source
ce sera number=some_numberen requête sql
tmm
écrivez un exemple de requête que vous voulez ou un exemple ... vous n'êtes pas assez clair.
Paras Sood
UPDATE table SET number = number - 1
tmm
Voir ma réponse mise à jour .....
Paras Sood
1
Techniquement, ce n'est pas parce que vous pouvez obtenir des conditions de course.
Fabian Schmengler