0

Magento を 1.7 から 1.8 にアップグレードした後 (いくつかの 3 番目の拡張機能がインストールされています)、製品を保存できなくなりました。製品を保存するたびに、次のエラーが発生します。

SQL エラー: SQLSTATE[21S01]: 挿入値リストが列リストと一致しません: 1136 列数が行 1 の値数と一致しません

デバッグ手法により、エラー クエリを見つけることができます。

SQL クエリ:

INSERT INTO `catalogrule_product_price`
 SELECT NULL AS `rule_product_price_id`,
 `dates`.`rule_date`,
 `t`.`customer_group_id`,
 `t`.`product_id`,
 MIN(rule_price) AS `rule_price`,
 1 AS `website_id`,
 `t`.`latest_start_date`,
 `t`.`earliest_end_date`
 FROM 
(SELECT `cppt`.`customer_group_id`, 
`cppt`.`product_id`, 
CASE WHEN IFNULL((@group_id), 'N/A') != cppt.grouped_id THEN @price := CASE `cppt`.`action_operator` WHEN 'to_percent' THEN cppt.price * cppt.action_amount/100 WHEN 'by_percent' THEN cppt.price * (1 - cppt.action_amount/100) WHEN 'to_fixed' THEN IF((cppt.action_amount < cppt.price), cppt.action_amount, cppt.price) WHEN 'by_fixed' THEN IF((0 > cppt.price - cppt.action_amount), 0, cppt.price - cppt.action_amount) END WHEN IFNULL((@group_id), 'N/A') = cppt.grouped_id AND IFNULL((@action_stop), 0) = 0 THEN @price := CASE `cppt`.`action_operator` WHEN 'to_percent' THEN @price * cppt.action_amount/100 WHEN 'by_percent' THEN @price * (1 - cppt.action_amount/100) WHEN 'to_fixed' THEN IF((cppt.action_amount < @price), cppt.action_amount, @price) WHEN 'by_fixed' THEN IF((0 > @price - cppt.action_amount), 0, @price - cppt.action_amount) END ELSE @price := @price END AS `rule_price`, `cppt`.`from_date` AS `latest_start_date`, `cppt`.`to_date` AS `earliest_end_date`, CASE WHEN IFNULL((@group_id), 'N/A') != cppt.grouped_id THEN @action_stop := cppt.action_stop WHEN IFNULL((@group_id), 'N/A') = cppt.grouped_id THEN @action_stop := IFNULL((@action_stop), 0) + cppt.action_stop END, @group_id := cppt.grouped_id,
 `cppt`.`from_time`,
 `cppt`.`to_time` 
FROM 
`catalogrule_product_price_tmp` AS `cppt`
 ORDER BY `cppt`.`grouped_id` ASC, 
`cppt`.`sort_order` ASC, 
`cppt`.`rule_product_id` ASC) AS `t` INNER JOIN (SELECT DATE_ADD(FROM_UNIXTIME(1382202000), INTERVAL -1 DAY) AS rule_date UNION SELECT FROM_UNIXTIME(1382202000) AS rule_date UNION SELECT DATE_ADD(FROM_UNIXTIME(1382202000), INTERVAL 1 DAY) AS rule_date) AS `dates` ON 1=1 WHERE (UNIX_TIMESTAMP(dates.rule_date) >= from_time) AND (IF((to_time = 0), 1, UNIX_TIMESTAMP(dates.rule_date) <= to_time)) 
GROUP BY `customer_group_id`, `product_id`, `dates`.`rule_date`;

このクエリでエラーが発生する理由を教えてください。ありがとう!

更新: 理由は、TBT Rewards モジュールが catalogrule_product_price テーブルに「rules_hash」という名前の列を追加したためです。

4

3 に答える 3

1

友人の Web サイト用に 1.9.2.2 にアップグレードしたところ、この問題が発生したため、ファイルに次のパッチを適用しました。

[magento/app/code/core/Mage/CatalogRule/Model/Action/Index/Refresh.php]

どのようなオンフロー効果があるかはわかりません。もちろん、このファイルが上書きされた場合、将来の更新ではこの機能を見逃さないように注意する必要がありますが、開始するには次の行を追加します。

'rules_hash'            => new Zend_Db_Expr('NULL'),

select ステートメントを次のようにします。

$select = $this->_connection->select()
        ->from($indexSelect, array())
        ->joinInner(
            array(
                'dates' => $this->_connection->select()->union(
                    array(
                        new Zend_Db_Expr(
                            'SELECT ' . $this->_connection->getDateAddSql(
                                $this->_connection->fromUnixtime($time),
                                -1,
                                Varien_Db_Adapter_Interface::INTERVAL_DAY
                            ) . ' AS rule_date'
                        ),
                        new Zend_Db_Expr('SELECT ' . $this->_connection->fromUnixtime($time) . ' AS rule_date'),
                        new Zend_Db_Expr(
                            'SELECT ' . $this->_connection->getDateAddSql(
                                $this->_connection->fromUnixtime($time),
                                1,
                                Varien_Db_Adapter_Interface::INTERVAL_DAY
                            ) . ' AS rule_date'
                        ),
                    )
                )
            ),
            '1=1',
            array()
        )
        ->columns(
            array(
                'rule_product_price_id' => new Zend_Db_Expr('NULL'),
                'rule_date'             => 'dates.rule_date',
                'customer_group_id'     => 'customer_group_id',
                'product_id'            => 'product_id',
                'rule_price'            => 'MIN(rule_price)',
                'website_id'            => new Zend_Db_Expr($website->getId()),
                'latest_start_date'     => 'latest_start_date',
                'earliest_end_date'     => 'earliest_end_date',
                /**
                Added because rules_hash was created by some module and not handled properly,
                see http://stackoverflow.com/questions/19480415/whats-wrong-with-this-magento-query
                */
                'rules_hash'            => new Zend_Db_Expr('NULL'),
            )
        )
        ->where(new Zend_Db_Expr($this->_connection->getUnixTimestamp('dates.rule_date') . " >= from_time"))
        ->where(
            $this->_connection->getCheckSql(
                new Zend_Db_Expr('to_time = 0'),
                new Zend_Db_Expr(1),
                new Zend_Db_Expr($this->_connection->getUnixTimestamp('dates.rule_date') . " <= to_time")
            )
        )
        ->group(array('customer_group_id', 'product_id', 'dates.rule_date'));

    return $select;
于 2016-01-29T16:26:15.667 に答える
0

そのクエリを生成している拡張機能を特定しましたか? insert ステートメントは、catalogrule_product_price テーブルの新しいフィールドを考慮していないようです。INSERT を特定の列に制限することで修正できます。

INSERT INTO `catalogrule_product_price`
VALUES (rule_product_price_id, rule_date, customer_group_id, product_id, rule_price, website_id, latest_start_date, earliest_end_date)
 SELECT NULL AS `rule_product_price_id`,
 `dates`.`rule_date`,
 `t`.`customer_group_id`,
 `t`.`product_id`,
 MIN(rule_price) AS `rule_price`,
 1 AS `website_id`,
 `t`.`latest_start_date`,
 `t`.`earliest_end_date`
 FROM 
(SELECT `cppt`.`customer_group_id`, 
`cppt`.`product_id`, 
CASE WHEN IFNULL((@group_id), 'N/A') != cppt.grouped_id THEN @price := CASE `cppt`.`action_operator` WHEN 'to_percent' THEN cppt.price * cppt.action_amount/100 WHEN 'by_percent' THEN cppt.price * (1 - cppt.action_amount/100) WHEN 'to_fixed' THEN IF((cppt.action_amount < cppt.price), cppt.action_amount, cppt.price) WHEN 'by_fixed' THEN IF((0 > cppt.price - cppt.action_amount), 0, cppt.price - cppt.action_amount) END WHEN IFNULL((@group_id), 'N/A') = cppt.grouped_id AND IFNULL((@action_stop), 0) = 0 THEN @price := CASE `cppt`.`action_operator` WHEN 'to_percent' THEN @price * cppt.action_amount/100 WHEN 'by_percent' THEN @price * (1 - cppt.action_amount/100) WHEN 'to_fixed' THEN IF((cppt.action_amount < @price), cppt.action_amount, @price) WHEN 'by_fixed' THEN IF((0 > @price - cppt.action_amount), 0, @price - cppt.action_amount) END ELSE @price := @price END AS `rule_price`, `cppt`.`from_date` AS `latest_start_date`, `cppt`.`to_date` AS `earliest_end_date`, CASE WHEN IFNULL((@group_id), 'N/A') != cppt.grouped_id THEN @action_stop := cppt.action_stop WHEN IFNULL((@group_id), 'N/A') = cppt.grouped_id THEN @action_stop := IFNULL((@action_stop), 0) + cppt.action_stop END, @group_id := cppt.grouped_id,
 `cppt`.`from_time`,
 `cppt`.`to_time` 
FROM 
`catalogrule_product_price_tmp` AS `cppt`
 ORDER BY `cppt`.`grouped_id` ASC, 
`cppt`.`sort_order` ASC, 
`cppt`.`rule_product_id` ASC) AS `t` INNER JOIN (SELECT DATE_ADD(FROM_UNIXTIME(1382202000), INTERVAL -1 DAY) AS rule_date UNION SELECT FROM_UNIXTIME(1382202000) AS rule_date UNION SELECT DATE_ADD(FROM_UNIXTIME(1382202000), INTERVAL 1 DAY) AS rule_date) AS `dates` ON 1=1 WHERE (UNIX_TIMESTAMP(dates.rule_date) >= from_time) AND (IF((to_time = 0), 1, UNIX_TIMESTAMP(dates.rule_date) <= to_time)) 
GROUP BY `customer_group_id`, `product_id`, `dates`.`rule_date`;
于 2013-10-22T03:51:46.577 に答える