web-dev-qa-db-ja.com

truncateTable()メソッドがクエリに対して空の文字列を作成し、行の削除に失敗するのはなぜですか?

次のコードでテーブルを切り詰めようとしています。 Joomlaのドキュメントでは、これでうまくいくと信じていますが、うまくいきません。何が欠けていますか?

_$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();
_

Echoステートメントは何も表示しません。コメントアウトされた行を使用してSQLを手動で生成すると、機能します。

truncateTable()関数の使用を検討している理由は、トランケーションをトランザクションに含めようとしているためです。手動のTRUNCATEステートメントを使用すると、トランザクションの別の部分が失敗しても、テーブルが切り捨てられます。他のステートメントは切り捨ての成功に依存しているため、これは厄介です。そのため、テーブルを空にする必要がないときにテーブルを空にすると、トランザクションを再度実行するためのデータが残りません。

1
Rob

更新:

setQuery()およびexecute()呼び出しはすでに関数スコープ内にあるようです...

から 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();
}
_

だからこれはあなたが切り捨てを呼び出す/実行する方法です(私はこれをテストしましたが、うまくいきます):

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

私も 複製されたStackoverflow質問の回答 を別の表現で投稿しました。


元の投稿:

この問題/バグはJoomlaコア開発者の注意を引く必要があると思います。

問題を再現できたことを確認できました。

_#__guineapig_テーブルで->truncateTable()を実行し、途中でいくつかのチェックポイントを含めました。

_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. 私が書いた場合:echo $truncate->dump();スクリプトが壊れて言った:

    致命的エラー:nullでのメンバー関数dump()の呼び出し

  2. エラーを回避するために->dump()を削除した場合、null文字列をクエリ(duh)として実行しても、ページは表示されます。

    構文エラー

  3. 生のクエリ_TRUNCATE #__guineapig_(setQuery()、次にexecute()を介して)を実行すると、すべての行が削除され、自動インクリメントインデックスが期待どおりにリセットされました。記録としては、$db->getNumRows()は不適切であり、機能しません。一方、$db->getAffectedRows()は_0_のカウントを生成しましたが、これは MySQLマニュアル が言うためです:

    切り捨て操作は、削除された行数の意味のある値を返しません。

  4. JDatabaseメソッド を使用するのに必死である(そしてあなたがそうする必要があるとは思わない)場合は、あなたを使用できますdelete()getAffectedRows()と通信しますが、これはまったく異なるプロセスであり、動作が異なります。特に、DELETEクエリは自動インクリメント数をリセットしません。以前のマニュアルへのリンクを参照して、TRUNCATEクエリの機能を正確に確認してください。
0
mickmackusa