web-dev-qa-db-fra.com

Pourquoi la méthode truncateTable () crée-t-elle une chaîne vide pour une requête et ne parvient-elle pas à supprimer des lignes?

J'ai le code suivant qui tente de tronquer une table. La documentation de Joomla me fait croire que cela fonctionnera, mais cela ne fonctionne pas. Qu'est-ce que je rate?

$db = JFactory::getDbo();
truncate_query = $db->getQuery(true);
//$truncate_query = 'TRUNCATE ' . $db->quoteName('#__mytable');
$truncate_query->truncateTable($db->quoteName('#__mytable'));
$db->setQuery($truncate_query);
echo $truncate_query;
exit();

L'instruction echo n'affiche rien. Si j'utilise la ligne commentée pour générer manuellement le code SQL, cela fonctionne.

La raison pour laquelle je cherche à utiliser la fonction truncateTable() est que j'essaie d'inclure la troncature dans une transaction. Lorsque j'utilise l'instruction TRUNCATE manuelle, la table est toujours tronquée, même si une autre partie de la transaction échoue. C'est agaçant puisque les autres déclarations reposent sur le succès de la troncature; Ainsi, si la table est vidée alors qu'elle ne devrait pas l'être, il ne reste plus de données pour exécuter la transaction à nouveau.

1
Rob

Mise à jour:

Il semble que les appels setQuery() et execute() se trouvent déjà dans la portée de la fonction ...

De https://github.com/joomla/joomla-cms/blob/staging/libraries/joomla/database/driver.php

/**
 * Method to truncate a table.
 *
 * @param   string  $table  The table to truncate
 *
 * @return  void
 *
 * @since   11.3
 * @throws  RuntimeException
 */
public function truncateTable($table)
{
    $this->setQuery('TRUNCATE TABLE ' . $this->quoteName($table));
    $this->execute();
}

Voici comment vous appelez/exécutez la troncature (je viens de tester ceci et cela fonctionne):

class modTrunctestHelper
{
    public function deleteAllRows(){
        JFactory::getDbo()->truncateTable('#__guineapig');
    }
}

J'ai également posté ne réponse sur votre question Stackoverflow répliquée avec un libellé différent.


Message original:

Je pense que ce problème/bogue devrait être porté à l'attention des développeurs principaux de Joomla.

Je peux confirmer que j'ai pu reproduire le problème.

J'ai exécuté ->truncateTable() sur ma table #__guineapig Et inclus quelques points de contrôle le long du chemin:

class modTrunctestHelper
{
    public function deleteAllRows(){
        $db = JFactory::getDbo();
        try {
            $truncate = $db->getQuery(true)
                           ->truncateTable('#__guineapig');
            // $truncate = 'TRUNCATE #__guineapig';
            // $truncate = $db->getQuery(true)
            //                ->delete('#__guineapig');
            echo $truncate->dump();
            $db->setQuery($truncate);
            $db->execute();
            echo $db->getAffectedRows() , 'Rows Of Data Deleted';
        } catch (Exception $e) {
            echo "Syntax Error" , $e->getMessage();
        }
    }
}
$TT = new modTrunctestHelper();
$TT->deleteAllRows();
  1. Si j’écrivais: echo $truncate->dump(); le script s’est cassé et a dit:

    Erreur fatale: appel à un membre de la fonction dump () sur null

  2. Si j’élimine ->dump() pour éviter l’erreur, alors l’exécution d’une chaîne null en tant que requête (duh) n’aide en rien, la page affichée:

    Erreur de syntaxe

  3. En exécutant la requête brute TRUNCATE #__guineapig (Via setQuery() puis execute()), toutes les lignes ont été supprimées et l'index auto-incrémenté a été réinitialisé comme prévu. Pour mémoire, $db->getNumRows() est inapproprié et ne fonctionne pas; while $db->getAffectedRows() a généré un nombre de 0 car le manuel MySQL dit:

    Les opérations de troncature ne renvoient pas de valeur significative pour le nombre de lignes supprimées.

  4. Si vous êtes désespéré (et je ne pense pas que vous ayez besoin de l'être) pour utiliser Méthodes JDatabase , alors vous pourriez utiliser delete() qui parlera à getAffectedRows() mais il s'agit d'un processus complètement différent avec des comportements différents. Notamment, les requêtes DELETE ne réinitialisent pas le numéro d'auto-incrémentation. Voir mon lien précédent au manuel pour voir exactement ce que font les requêtes TRUNCATE.
0
mickmackusa