1

我有一个表 sessionBasket,其中包含我网站访问者购物篮中的物品列表。看起来像:

id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
usersessid VARCHAR
date_added DATETIME
product_id INT
qty INT

我的添加到购物篮脚本首先检查此表中是否存在与 usersessid 关联的当前 product_id 的项目,如果找到,它会更新数量。如果不是,则单独的查询会插入包含相关信息的新行。

从那以后,我发现重复密钥更新存在一个条件,但我不确定我需要更改什么才能使其正常运行。我在这里需要两个键 - product_id 和 usersessid,如果有一行这两个键都与我要插入的键相匹配,则生成更新条件。我确信有比我已经做的更好的方法来做到这一点。此外,我检查 product_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_id,这会将唯一索引折叠成一个而不是两个字段,但这并不理想。

4

1 回答 1

4

首先你需要一个唯一的索引(usersessid, product_id)。我不确定您是否真的在使用自动生成的列id,但如果没有,您应该将主键更改为(usersessid, product_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);
于 2009-10-05T11:01:02.317 回答