【问题标题】:MySQL Duplicate Entry for non Unique column update in WordPressWordPress中非唯一列更新的MySQL重复条目
【发布时间】:2019-09-14 13:17:18
【问题描述】:

在 WordPress 中,如果购物车中已经存在记录,我想将数量更新 +1(在代码中查询)。

三列在表中是唯一的。更新 qty 列时,此代码中出现重复输入错误。但是,如果我使用来自控制台的直接查询,它会更新 qty 值而不会出错。

我也在 AjAX 中调用了这个方法。那是返回未定义的(可能在 ajax 错误中)。

那么我怎样才能让这段代码与 Ajax 一起工作,如果没有记录而不是插入 else 只需将 qty 值更新为 +1

$this->gs_db是数据库类实例,$this->gs_db->db$wpdb

表格

CREATE TABLE IF NOT EXISTS wp_gs_pg_cart (
id            BIGINT(20) AUTO_INCREMENT UNIQUE NOT NULL,
product_group BIGINT(20)                       NOT NULL,
qty           INT(11)                          NOT NULL,
group_id      BIGINT(20)                       NOT NULL,
group_admin   BIGINT(20)                       NOT NULL,
group_user    BIGINT(20)                       NOT NULL,
added_at      DATETIME DEFAULT NOW()           NOT NULL,
PRIMARY KEY (id),
INDEX pg_cart_index (ID, product_group, group_id, group_admin, group_user),
UNIQUE pg_cart_unique (product_group, group_id, group_user)
);

类方法

/**
 * Add product group into the cart
 *
 * @param int      $group_id      group id
 * @param int      $product_group product group id
 * @param int|bool $group_user    group user / logged in id
 *
 * @return int inserted row id if new else update row id
 */
public function add_pg_to_cart($group_id, $product_group, $group_user = FALSE)
{

    $this->group_id      = $group_id;
    $this->qty           = 1;
    $this->product_group = $product_group;
    $this->group_admin   = $this->group_id;
    $this->group_user    = ($group_user) ? absint($group_user) : absint(get_current_user_id());

    // check if record is already exists
    $query = "SELECT * FROM wp_gs_pg_cart WHERE product_group = '%d' AND group_id = '%d' AND group_user = '%d'";

    $prepare = $this->gs_db->db->prepare($query, $this->product_group, $this->group_id, $this->group_user);
    $result  = $this->gs_db->db->get_row($prepare);

    if ($this->gs_db->db->num_rows > 0) {
        $this->qty += $result->qty;

        $this->gs_db->db->update($this->gs_db->get_pg_cart_table(), ['qty' => $this->qty], ['id' => $result->id], '%d');

        $this->id = $result->id;
    } else {

        // setup data to insert
        $this->data = [
            'product_group' => $this->product_group,
            'qty'           => $this->qty,
            'group_id'      => $this->group_id,
            'group_admin'   => $this->group_admin,
            'group_user'    => $this->group_user,
        ];

        // setup data format
        $this->format = [
            '%d',
            '%d',
            '%d',
            '%d',
            '%d',
        ];

        // insert record
        $this->gs_db->db->insert($this->gs_db->get_pg_cart_table(), $this->data, $this->format);

        // get the id for inserted record
        $this->id = $this->gs_db->db->insert_id;

    }

    return $this->id;

}

Ajax 回调函数

function gs_pg_add_to_cart_ajax()
{

    // Check if user is logged in
    if ( ! is_user_logged_in()) {
        // throw error if user is not logged in
        wp_send_json_error(__('Please login to order', 'group-shop'));

        // we use this manually as want to print error
        wp_die();
    }

    // check and validate nonce
    if ( ! check_ajax_referer('gs_nonce', 'nonce', FALSE)) {

        // throw error if validation fails
        wp_send_json_error(__('Do not be nasty with validation', 'group-shop'));
    }

    $group_id      = 0;
    $product_group = 0;
    $cart_id       = 0;

    // validate product_group
    if ( ! isset($_POST[ 'product_group' ]) || empty($_POST[ 'product_group' ]) || $_POST[ 'product_group' ] <= 0) {
        // throw error if validation fails
        wp_send_json_error(__('Product Group is not defined', 'group-shop'));
    } else {
        $product_group = absint($_POST[ 'product_group' ]);
    }

    // validate product_group
    if ( ! isset($_POST[ 'group_id' ]) || empty($_POST[ 'group_id' ]) || $_POST[ 'group_id' ] <= 0) {
        // throw error if validation fails
        wp_send_json_error(__('Group is not defined', 'group-shop'));
    } else {
        $group_id = absint($_POST[ 'group_id' ]);
    }

    // initialize cart object
    $cart = new Group_Shop_Cart();
    // insert record
    $cart_id = $cart->add_pg_to_cart($group_id, $product_group);

    // if record inserted
    if ($cart_id > 0) {

        // show success message once record inserted
        wp_send_json_success(__('Product is added to cart', 'group-shop'));

    } else {

        // throw error if fails to insert record
        wp_send_json_error(__('Something went wrong', 'group-shop'));

    }

    // stop further execution once all process done
    wp_die();

}

Javascript

(function ($) {

    $(function () {

        let response_alert = $('#response');
        response_alert.hide();

        $('form.gsGpAddToCart').on('submit', function (e) {
            e.preventDefault();

            let formData = $(this).serialize();

            $.ajax({

                method: 'POST',
                dataType: 'json',
                url: ajax_vars.ajax_url,
                data: formData + "&action=gs_pg_add_to_cart&nonce=" + ajax_vars.nonce,
                success: function (response) {

                    console.log(response);

                    let response_alert = $('#response');

                    if (response.success === true) {
                        response_alert.fadeIn().prepend(alerts('success', response.data));
                    }

                    if (response.success === false) {
                        response_alert.fadeIn().prepend(alerts('error', response.data));
                    }

                },
                error: function (response) {

                    let error_message = (response.data === undefined) ? 'Something went wrong!' : response.data;
                    response_alert.fadeIn().prepend(alerts('error', error_message));
                    gs_alert_stats();
                },
                complete: function () {
                }
            });

            return false;
        });

        // control dynamically created error with JS - close/hide
        function gs_alert_stats() {
            let gs_alert = $('.gs-message');
            $('.gs-close').on('click', function () {
                alerts('Clicked');
                $(this).parent(gs_alert).fadeOut();
            });
        }

    });

})(jQuery);

Javascript 正在返回此错误响应 Something went wrong!,它位于 error: function (response)

【问题讨论】:

    标签: php mysql sql wordpress


    【解决方案1】:

    您可以使用 MySQL INSERT ... ON DUPLICATE KEY 语法来简化整个逻辑。

    来自the documentation

    如果您指定 ON DUPLICATE KEY UPDATE 子句并且要插入的行会导致 UNIQUE 索引或 PRIMARY KEY 中的重复值,则会发生旧行的 UPDATE。

    您已经有了适当的UNIQUE 约束,因此您只需调整类方法的代码即可立即使用以下查询:

    INSERT INTO wp_gs_pg_cart(product_group, group_id, group_admin, group_user, qty)
    VALUES(%d, %d, %d, %d, 1)
    ON DUPLICATE KEY UPDATE qty = qty + 1
    

    【讨论】:

    • 所以这里我不必单独检查现有条目。哇,太好了。我完全没有意识到这一点......让我试试。非常感谢。
    • @CodeLover:确切地说,你不需要代码中的所有逻辑,因为 MySQL 几乎已经内置了对那个用例的支持......
    • 这工作正常,除了一个问题。它给出了错误的 AJAx 响应。我的意思是它在插入/更新时返回error: function(response) 代码。
    • @CodeLover:好的,所以您的 ajax 代码可能存在问题。您最初提到您在 Ajax 中没有得到适当的响应。我不是 Ajax 人,这超出了我的技能范围......
    • 感谢@CodeLover。您可能想专门针对 ajax 问题提出另一个问题(使用相关标签,如 ajaxjavascript、...)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    相关资源
    最近更新 更多