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?


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ë.


/ 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.


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.