Php 在重复键上插入新记录,而不是使用唯一键进行更新

Php 在重复键上插入新记录,而不是使用唯一键进行更新,php,mysql,Php,Mysql,我有一个问题,我的插入。。。当重复键更新插入新记录而不是更新行时,我使用的表同时具有主键和唯一键。所以我对为什么会发生这种情况感到困惑 桌子 质疑 $add_product_errors=array(); 如果(isset($_POST['add'])){ $item\u name=$\u POST['item\u name']; $desc=$_POST['desc']; $price=$_POST['price']; $rest\u id=mysqli\u real\u escape\u字符

我有一个问题,我的插入。。。当重复键更新插入新记录而不是更新行时,我使用的表同时具有主键和唯一键。所以我对为什么会发生这种情况感到困惑

桌子

质疑

$add_product_errors=array();
如果(isset($_POST['add'])){
$item\u name=$\u POST['item\u name'];
$desc=$_POST['desc'];
$price=$_POST['price'];
$rest\u id=mysqli\u real\u escape\u字符串($dbc,$\u SESSION['Resturant\u id']);
如果(空($_POST['price'])| |!筛选变量($_POST['price'],筛选验证浮动)| |($_POST['price']

我对语法很反感。也许可以先在控制台或MySQL workbench中编写SQL并对其进行测试,或者先在其他地方进行测试。试试以下方法:

$query = "INSERT INTO Product(Resturant_ID,Product_Name,Product_Desc,Product_Price) VALUES (?,?,?,?) 
    ON DUPLICATE KEY UPDATE
        Resturant_ID = ?
        ,Product_Name = ?
        ,Product_Desc = ?
        ,Product_Price = ?";

    $run_query = mysqli_prepare($dbc, $query);
    if (!$run_query) {
        die(mysqli_error($dbc));
    }
    mysqli_stmt_bind_param($run_query, 'issdissd', $rest_id, $item_name, $desc, $price, $rest_id, $item_name, $desc, $price);
或者可能是
八次,绑定两次…不确定mysqli是否支持命名参数


根据Martin的反馈[再次]进行了更新。

我对语法很感兴趣。也许可以尝试先编写SQL并在console或MySQL workbench或其他任何地方进行测试。尝试以下方法:

$query = "INSERT INTO Product(Resturant_ID,Product_Name,Product_Desc,Product_Price) VALUES (?,?,?,?) 
    ON DUPLICATE KEY UPDATE
        Resturant_ID = ?
        ,Product_Name = ?
        ,Product_Desc = ?
        ,Product_Price = ?";

    $run_query = mysqli_prepare($dbc, $query);
    if (!$run_query) {
        die(mysqli_error($dbc));
    }
    mysqli_stmt_bind_param($run_query, 'issdissd', $rest_id, $item_name, $desc, $price, $rest_id, $item_name, $desc, $price);
或者可能是
八次,绑定两次…不确定mysqli是否支持命名参数


更新[再次]根据Martin的反馈。

您没有在更新时更改
中的值。
-。另外还有一个说明:建议不要在重复更新时使用
中包含多个唯一密钥的
它。它可能看起来很干净,但如果您要求产品名称唯一,您最好在代码中处理它。然后您可以加载duplica在一条漂亮的错误消息中显示产品并将其显示给用户。
Resturant\u ID bigint(255)NOT NULL
这太大了,会占用不成比例的时间、ram和存储空间。括号中的数字定义的是值的长度,而不是实际值本身,因此您将此数字设置为最多255位。作为比较,您可能需要超过8位。自1970年以来,每秒的值仅为10位“数字长。@Martin因为该网站是为特许经营而建立的,目前有90家特许经营,而且还在增长,我特意将其设为255家,只是为了覆盖公司的增长。有些特许经营每家都有50多家餐厅。但我明白你在MySQL中的意思,比如
int
smallint
bigint
不依赖于提供的长度值。根据定义,
bigint
始终使用8个字节。只有在使用
zerofill
时,长度值才很重要,然后将使用
0
填充该值以达到指定的长度。(如果需要更多字符,数字仍会完整打印。)一个
int
使用4个字节,可以存储超过40亿的数字(列必须是无符号的,但负ID无论如何都没有意义。
auto_increment
aways返回正数)。您在更新时没有更改
中的值。另外还有一个说明:建议不要在重复更新时使用带有多个唯一键的
它。它可能看起来很干净,但如果您要求产品名称唯一,则最好在代码中处理此问题。然后,您可以加载重复的产品并将其显示给用户用户将收到一条漂亮的错误消息。
Resturant\u ID bigint(255)NOT NULL
这太大了,会占用不成比例的时间、ram和存储空间。括号中的数字定义的是值的长度,而不是实际值本身,因此您将此数字设置为最多255位。作为比较,您可能需要超过8位。自1970年以来,每秒的值仅为10位“数字长。@Martin因为该网站是为特许经营而建立的,目前有90家特许经营,而且还在增长,我特意将其设为255家,只是为了覆盖公司的增长。有些特许经营每家都有50多家餐厅。但我明白你在MySQL中的意思,比如
int
smallint
bigint
不依赖于提供的长度值。根据定义,
bigint
始终使用8个字节。只有在使用
zerofill
时,长度值才很重要,然后将使用
0
填充该值以达到指定的长度。(如果需要更多字符,数字仍会完整打印。)一个
int
使用4个字节,可以存储超过40亿的数字(列必须是无符号的,但负ID无论如何都没有意义。
auto_increment
aways返回正数)。当OPs连接是MySQLi连接时,您正在使用PDO语法。对于MySQLi准备的语句,问号是正确的。哈哈,快到了-您需要扩展
sssd
以合并重复变量:-)更新:)现在看起来好像有人在键盘上昏倒了。我现在懒得停下来看看页面。至少我学到了一些东西!希望我能让Martin对我自己的代码进行同行评议;)当OPs连接是MySQLi连接时,您正在使用PDO语法。对于MySQLi准备的语句,问号是正确的。哈哈,快到了-您需要扩展
sssd
以合并重复变量:-)更新:)现在看起来好像有人在键盘上昏倒了。我现在费心停下来看看页面。至少我学到了一些东西!希望我能让Martin对我自己的代码进行同行评议;)
$query = "INSERT INTO Product(Resturant_ID,Product_Name,Product_Desc,Product_Price) VALUES (?,?,?,?) 
    ON DUPLICATE KEY UPDATE
        Resturant_ID = ?
        ,Product_Name = ?
        ,Product_Desc = ?
        ,Product_Price = ?";

    $run_query = mysqli_prepare($dbc, $query);
    if (!$run_query) {
        die(mysqli_error($dbc));
    }
    mysqli_stmt_bind_param($run_query, 'issdissd', $rest_id, $item_name, $desc, $price, $rest_id, $item_name, $desc, $price);