Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 关于重复密钥更新的实现/设计_Mysql_Insert_Duplicates - Fatal编程技术网

Mysql 关于重复密钥更新的实现/设计

Mysql 关于重复密钥更新的实现/设计,mysql,insert,duplicates,Mysql,Insert,Duplicates,我有一个叫做sessionBasket的表,它包含了我网站访问者购物篮中的项目列表。它看起来像: id INT NOT NULL AUTO_INCREMENT PRIMARY KEY usersessid VARCHAR date_added DATETIME product_id INT qty INT 我的add to basket脚本首先检查该表中是否存在与usersessid相关联的当前product_id的项目,如果找到了,则更新qty。否则,单独的查询将插入包含相关信息的新行 我已

我有一个叫做sessionBasket的表,它包含了我网站访问者购物篮中的项目列表。它看起来像:

id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
usersessid VARCHAR
date_added DATETIME
product_id INT
qty INT
我的add to basket脚本首先检查该表中是否存在与usersessid相关联的当前product_id的项目,如果找到了,则更新qty。否则,单独的查询将插入包含相关信息的新行

我已经发现有一个条件重复密钥更新,但我不知道我需要改变什么,使其正常工作。这里我需要两个键——product_id和usersessid,如果有一行同时包含这两个键,并且这两个键都与我尝试插入的键匹配,那么就会生成更新条件。我相信有比我现在做的更好的方法。另外,我会检查产品的id是否有效,以防它被欺骗,所以总体来说,我会进行两次查询以检查内容,然后进行另一次更新/插入

以下是单独的查询:

//do select query to verify item id
$check_sql = "SELECT * FROM aromaProducts1 WHERE id='".intval($_GET["productid"])."'";
$check_res = mysqli_query($mysqli, $check_sql) or  error_log(mysqli_error($mysqli)."\r\n");

  //do select query to check for item id already in basket
  $duplicate_sql = "SELECT qty FROM sessionBasket WHERE product_id='".intval($_GET["productid"])."' AND usersessid='".session_id()."'";
  $duplicate_res = mysqli_query($mysqli, $duplicate_sql) or  error_log(mysqli_error($mysqli)."\r\n");

    //item in basket - add another
    $add_sql = "UPDATE sessionBasket SET qty=qty+".intval($_GET["qty"])."  WHERE usersessid='".session_id()."'AND product_id='".intval($_GET["productid"])."'";
    $add_res = mysqli_query($mysqli, $add_sql) or  error_log(mysqli_error($mysqli)."\r\n");

  //insert query
  $insert_sql = "INSERT INTO ".$table." (userid, usersessid, date_added, product_id, qty, notes) VALUES (
  '".$userid."',
  '".session_id()."',
  now(),
  '".htmlspecialchars($productid)."',
  '".intval($_GET["qty"])."',
  '".htmlspecialchars($notes)."')";
  $insert_res = mysqli_query($mysqli, $insert_sql) or  error_log(mysqli_error($mysqli)."\r\n");
请不要回复有关SQL注入的信息-我的清理工作比这些代码片段透露的要彻底得多


任何缩小这些尺寸的帮助都是非常好的。我的表格可能不够规范。我认为可以创建一个新的唯一字段,其中包含连接的usersessid和product\u id,这会将唯一索引折叠为一个而不是两个字段,但这并不理想。

首先,您需要在
(usersessid,product\u id)
上创建一个唯一索引。我不确定您是否实际使用了自动生成的列
id
,但如果不是,您应该将主键更改为
(usersessiond,product\u id)
。然后,不运行单独的
UPDATE
查询,只运行单个
INSERT
查询:

INSERT INTO sessionBasket (userid, usersessid, date_added, product_id, qty, notes)
VALUES (?, ?, now(), ?, ?, ?)
ON DUPLICATE KEY UPDATE qty = qty + ?
为了明确唯一索引应该是什么样子:

CREATE UNIQUE INDEX sessionBasket_uniq ON sessionBasket (usersessid, product_id);
或主键:

ALTER TABLE sessionBasket ADD CONSTRAINT sessionBasket_pkey PRIMARY KEY (usersessid, product_id);

首先,您需要在
(usersessid,product\u id)
上有一个唯一的索引。我不确定您是否实际使用了自动生成的列
id
,但如果不是,您应该将主键更改为
(usersessiond,product\u id)
。然后,不运行单独的
UPDATE
查询,只运行单个
INSERT
查询:

INSERT INTO sessionBasket (userid, usersessid, date_added, product_id, qty, notes)
VALUES (?, ?, now(), ?, ?, ?)
ON DUPLICATE KEY UPDATE qty = qty + ?
为了明确唯一索引应该是什么样子:

CREATE UNIQUE INDEX sessionBasket_uniq ON sessionBasket (usersessid, product_id);
或主键:

ALTER TABLE sessionBasket ADD CONSTRAINT sessionBasket_pkey PRIMARY KEY (usersessid, product_id);

好的,我试试看。使这些字段唯一不仅允许一个人拥有特定的项目,而且不允许其他人拥有特定的项目吗?这个篮子不是一次供一个用户使用的,它可以供几十个用户使用。例如,我希望不止一个人能够拥有product_id 1……两列上都有一个唯一的索引/主键,而不仅仅是其中一列()。它将确保每个
usersessid、product\u id
组合只有一行。太好了-我不确定这是怎么回事。非常感谢:)太好了,我试试看。使这些字段唯一不仅允许一个人拥有特定的项目,而且不允许其他人拥有特定的项目吗?这个篮子不是一次供一个用户使用的,它可以供几十个用户使用。例如,我希望不止一个人能够拥有product_id 1……两列上都有一个唯一的索引/主键,而不仅仅是其中一列()。它将确保每个
usersessid、product\u id
组合只有一行。太好了-我不确定这是怎么回事。非常感谢:)