如果行存在则更新mysql表如果不添加新的

Posted

技术标签:

【中文标题】如果行存在则更新mysql表如果不添加新的【英文标题】:Update mysql table if row excist if not add new 【发布时间】:2014-07-04 14:16:33 【问题描述】:

首先我有 js/jquery/ajax 代码:

$('#sacuvajMapu').click(function (e) 
 $.ajax(
            url: "insertMap.php",
            type: "POST",
            async: true, 
            data:  ajdi:ajdi, mapData:$('#mapData').val();, //your form data to post goes here as a json object
            dataType: "html",

            success: function(data) 
            console.log(data);
             
            error: function(data) 
            console.log(data);
            
        );
        );


        );

我也有mysql数据库:

现在我需要用我的 ajax 代码将数据插入数据库,所以我写:

      try         
            $STH = $db->prepare("INSERT INTO map (id_parcele, json, user_id)
VALUES (:1,:2,:3);");

            $STH->bindParam(':1', $_POST['ajdi']);
            $STH->bindParam(':2', $_POST['mapData']);
            $STH->bindParam(':3', $user_id);

一切正常。

现在我有一个问题。 我必须检查值$_POST['ajdi'] 是否在表列id_parcele 中,如果只是用来自$_POST['mapData'] 的值更新表列json,如果POST['ajdi'] 在表列id_parcele 中不存在,那么我需要用上面的数据添加新行...

我该怎么做? 什么是正确的方法?

【问题讨论】:

您可以使用rowCount() 来检查一行是否存在。这是一种选择。 在 mysql 中,您可以指定 insert ... on duplicate key update 语法,如果键已经存在,它将更新一行。 dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html 【参考方案1】:

假设已经存在的记录会抛出主键冲突,你可以这样做:

INSERT INTO map (id_parcele, json, user_id)
VALUES (:1,:2,:3)
on duplicate key update json=values(json), user_id=values(user_id)

这种语法是 MySQL 特有的。 http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

【讨论】:

我这样写:尝试 $STH = $db->prepare("INSERT INTO map (id_parcele, json, user_id) VALUES (:1,:2,:3) on duplicate key update json =values(json), user_id=values(user_id)"); $STH->bindParam(':1', $_POST['ajdi']); $STH->bindParam(':2', $_POST['mapData']); $STH->bindParam(':3', $user_id);但再次添加相同的数据作为新行... id_parcele 是否设置为主键? 不,你可以从上面的照片中看到我的主要是 ID,id_parcele 必须是唯一的? 是的。如果您没有在列列表中包含唯一标识,则此方法不起作用。 当我尝试将其设为主要时,我得到:1075 - 表定义不正确;只能有一个自动列,并且必须定义为一个键【参考方案2】:

您可以通过单个查询来执行此操作(只要您在 id_parcele 上放置一个唯一键),具体如下:

http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

INSERT INTO map (id_parcele, json, user_id)
VALUES (:1,:2,:3)
on duplicate key update json=// etc etc

如果您只是想每次都替换值,也可以使用Replace Into 语法:

REPLACE 的工作方式与 INSERT 完全相同,只是如果表中的旧行与 PRIMARY KEY 或 UNIQUE 索引的新行具有相同的值,则在插入新行之前删除旧行。请参见第 13.2.5 节,“INSERT 语法”。

replace INTO map (id_parcele, json, user_id)
VALUES (:1,:2,:3)

不过,您需要在id_parcele 上拥有一个主键或唯一索引。

不同之处在于replace into 语法将首先删除旧行,然后在查询值中插入您拥有的任何内容 - 而on duplicate... 语法允许您执行诸如添加计数器以查看有多少更新的操作通过使用其中的值已经发生在该行上:

假设您的原始行是在名为 parcel_updates 的字段中使用 0 创建的(并且有这样一列),您可以执行以下操作:

INSERT INTO map (id_parcele, json, user_id, parcel_updates)
VALUES (:1,:2,:3,0)
on duplicate key update parcel_updates=parcel_updates+1

这将保持原始值不变,但将 parcel_updates 字段中的计数增加一。

编辑:索引

要add an index 到一个已经存在的表,你需要运行这样的东西(只需要一次),这些类型的命令才会起作用:

CREATE unique INDEX parcelID ON map (id_parcele);

这样一来,id_parcele 的相同值将不会超过一行。但是,您应该确保您没有多次在其中拥有相同的值。您也可以在建表时define a column as unique(供以后参考):

create table map(
id_parcele int(10) unique key,
// etc etc

【讨论】:

+1,关于REPLACE 的优点。我还要添加一条评论,即 DELETE 操作(如果发生)将导致表上的任何删除触发器被触发,并且(如果 InnoDB 引擎)将调用任何引用外键的 ON DELETE 规则(CASCADE ,设置为空,限制)。 (您指定将执行 DELETE 操作;我只想强调它是一个真正的删除。可能不是 OP 关心的问题,但在更一般的情况下,我们需要这样做知道。 我写:尝试 $STH = $db->prepare("INSERT INTO map (id_parcele, json, user_id) VALUES (:1,:2,:3) on duplicate key update json=值(json),user_id=值(user_id)”); $STH->bindParam(':1', $_POST['ajdi']); $STH->bindParam(':2', $_POST['mapData']); $STH->bindParam(':3', $user_id);但再次添加与新行相同的数据... @gmaestro 我进行了编辑,解释了如何在表上创建唯一索引,以便这些 SQL 查询适合您。 谢谢,但我是在 phpmyAdmin 中完成的,非常感谢您的帮助

以上是关于如果行存在则更新mysql表如果不添加新的的主要内容,如果未能解决你的问题,请参考以下文章

MySQL:如果值存在,则对行进行更新,如果值不存在,则插入 [重复]

SQL 查询 - 如果存在则更新,否则插入

sql 示例:如果行存在,则如何更新行或如​​果行不存在则插入行

mysql批量更新,数据存在则更新,不存在则插入

如果行存在于另一个表中,如何更新 (SQL)

如果行不存在具有相同的值,如何在 Mysql 中插入行