PHP 中如果值存在则 MySQL 更新,如果不存在则插入?

Pau*_*can 2 php mysql

$sql_career = "REPLACE INTO career
         (id, battletag, lastHeroPlayed, lastUpdated, monsters, elites, hardcoreMonsters, barbarian, crusader, demonhunter, monk, witchdoctor, wizard, paragonLevel, paragonLevelHardcore)
         VALUES
         ('', '$battletag', '$lastHeroPlayed', '$lastUpdated', '$monsters', '$elites', '$hardcoreMonsters', '$barbarian', '$crusader', '$demonhunter', '$monk', '$witchdoctor', '$wizard', '$paragonLevel', '$paragonLevelHardcore')";
Run Code Online (Sandbox Code Playgroud)

ID自动递增。 battletag是独特的。

其他一切都会随着时间而改变。因此,如果条目已经存在,我想替换或更新条目battletag而不创建新的id。如果它不存在,我希望它创建一个新条目,让id该唯一的自动增量battletag


这可以解决一个问题:

 $sql_career = "
    insert INTO career
      (id, battletag, lastHeroPlayed)
    VALUES
      (NULL, '$battletag', $lastHeroPlayed)
    on duplicate key
      update lastHeroPlayed=$lastHeroPlayed;
 ";
Run Code Online (Sandbox Code Playgroud)

例如,如果我加载两个唯一的行,则每个行的 ID 自动递增到 1,然后递增到 2。然后,如果我加载的行具有现有行之一的唯一键的重复项(然后按预期更新),这实际上会触发自动增量。因此,如果我添加第三个唯一行,其编号将是 4 而不是 3。

我怎样才能解决这个问题?

Flu*_*feh 5

您想使用on duplicate key ... update 语法而不是替换为。

定义一个唯一列(主索引或唯一索引),然后在语句中检查它,如下所示:

INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
  ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
Run Code Online (Sandbox Code Playgroud)

与替换成相比,使用此命令的好处是替换成将始终删除您已有的数据,并将其替换为您第二次提供的数据(有点像命令名称所暗示的那样)。然而,一条update on...语句只会更新您在其第二部分中定义的列(如果找到重复项),因此您可以将信息保留在您想要保留的列中。

基本上你的命令看起来像这样(仅重要列的缩写)

$sql_career = "
    insert INTO career
        (id, battletag, heroesKilled)
    VALUES
        ($id, '$battletag', $heroesKilled)
    on duplicate key
        update heroesKilled=heroesKilled+1;

";
Run Code Online (Sandbox Code Playgroud)

再次请记住,在您的表中,您需要在 Battletag 上强制使用唯一列 -主键或唯一索引。您可以通过代码或通过 phpMyAdmin 之类的工具(如果您已安装)执行此操作一次。

编辑:好的,我可能发现了一个小宝石(大约在页面的三分之一处)可能会起作用 - 虽然我自己从未使用过它,但你能为我尝试以下操作吗?

$sql_career = "
    insert ignore INTO career
        (id, battletag, heroesKilled)
    VALUES
        (null, '$battletag', $heroesKilled)
    on duplicate key
        update heroesKilled=heroesKilled+1;

";
Run Code Online (Sandbox Code Playgroud)

在文档的这一页中似乎也有支持这一点的协作证据:

如果使用 INSERT IGNORE 并且忽略该行,则 AUTO_INCRMENT 计数器不会递增,并且 LAST_INSERT_ID() 返回 0,这反映没有插入行。