【问题标题】:SQL INSERT INTO table results in duplicatesSQL INSERT INTO 表导致重复
【发布时间】:2016-02-19 22:29:17
【问题描述】:

我有一个脚本,我已经设置了一个 CRON,它通过 JSON (cURL) 从第 3 方服务器获取值

现在每次 cron 运行时都会插入一条全新的记录。导致重复,并导致我手动删除重复。

我将如何防止重复,只更新丢失的信息或与新 $VAR 值不同的信息?

我想做的可以这样表达:IF old value is NOT new value use new value else use old value;

    if ($stmt->num_rows !== 1) {
    if ($insert_stmt = $mysqli->prepare("
                                        INSERT INTO members (
                                                            start_date
                                                            )

                                        VALUES (?)")) 

        {
        $insert_stmt->bind_param('s',
                                $StartDate, 

                                );

    if (! $insert_stmt->execute()) { echo ''; }
        }
}
}

【问题讨论】:

  • 您是否尝试过 INSERT ... ON DUPLICATE KEY UPDATE dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
  • 是的。您不能使用 VALUE 执行 Insert ... ON DUPLICATE key UPDATE
  • @MyWay - 他需要在INSERT 语句中包含PRIMARY KEY(或至少一个UNIQUE 键) - 我猜还不是这样,
  • @MarkusWMahlberg 哈哈

标签: php mysql cron


【解决方案1】:

您应该尝试使用INSERT ... ON DUPLICATE KEY UPDATEDocumentation

这确实意味着您必须为表定义一些始终不变的 唯一(可能是 )键,以便 MySQL 知道要更新什么。

一个简单的例子来说明你将如何做到这一点:

INSERT INTO table (f1,f2,f3) VALUES ('something_unique',2,5) 
ON DUPLICATE KEY UPDATE f2=2,f3=5

【讨论】:

  • `INSERT INTO .. SELECT .. FROM ... ON DUPLICATE KEY UPDATE val = VALUES(val) 获取将使用 VALUES() 插入的值仅适用于 INSERT INTO .... VALUES (...)
  • 所以我可以做类似$var = xx123 的事情并将其作为虚拟列/值传递给数据库表?现在我考虑了一下……这个值在我检索的 JSON 数据中不会是唯一的。只有recordemail @abdrius 才是真正令人不安的
  • 好吧,任何唯一的(并在数据库中设置为一个)都可以解决问题!
  • @LeviZoesch - 您是否从 JSON 中获取成员 ID(PRIMARY KEY - 大概有一个,可能在数据库中称为 members.id)?如果是这样,那就是您的独特数据。只需尝试在INSERT 语句中设置members.id。如果该记录已存在,将触发ON DUPLICATE KEY UPDATE
  • 我说的是我从 3rd 方服务器获得的值不包含这个 new 虚构的唯一值。这只会站在我这边,那么进来的 JSON 与旧的有什么区别呢?我可以交叉引用进入我的数据库的唯一事情是 recordvalue 不一样... @CD001
【解决方案2】:

如果数据库中已经存在带有UNIQUEPRIMARY KEY 标志的字段之一,则以下语句将被忽略。如果您正在搜索INSERT IF NOT EXISTS,这可能就是您正在寻找的内容:

INSERT IGNORE INTO `members` SET name='Steve',start_date='2015-11-20';

您还可以使用REPLACE 覆盖已存在的记录。如果它还不存在,它将被创建:

REPLACE INTO `members` SET name='Steve',start_date='2015-11-20';

要考虑的另一件事是INSERT ... ON DUPLICATE KEY UPDATE 语法:

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

UPDATE table SET c=c+1 WHERE a=1;

【讨论】:

  • 我很感激。我最终为记录 # 中的 if 值为 true 编写了 else if 语句。昨晚搞定了,但我很感激。
  • 查看我发布的对我有用的答案@NextLocal
【解决方案3】:

我最终编写了另一个 if 语句来检查传入的唯一值是否存在以及现有的 db 值是否存在并将其留空以防止它导入重复项。我还编写了一个单独的文件来更新我收到的(新)和数据库中的(旧)值之间的区别,这实际上对我的应用程序非常有用。

这是我对遇到此问题的其他人的回答:)

$prep_stmt = "SELECT * FROM table WHERE column_keys=?";
    $stmt = $mysqli->prepare($prep_stmt);

    if ($stmt) {
        $stmt->bind_param('s',$varvalues);
        $stmt->execute();
        $stmt->store_result();

        if ($stmt->num_rows == 1) {

        if ($insert_stmt = $mysqli->prepare("")) {
            $insert_stmt->bind_param('');

            if (! $insert_stmt->execute()) { 
                echo 'shits broke'; }
            }
        } 
        else { if ($insert_stmt = $mysqli->prepare("
                                            INSERT INTO table (column_keys)
                                            VALUES (?)")) // you will need a ? per column seperate by a , (?,?,?...?)

            { $insert_stmt->bind_param('s',
                                    $varvalues
                                    ); // you will also need to bind a 's' (string) 'i' for num, etc per $var value.

        if (! $insert_stmt->execute()) { echo 'shits broke';} //lol 
            }
    }
    }

我偶然发现了一个简单的错误报告技巧,它帮助我清理了一些我忽略的东西。只需将它放在文件的顶部,或者您要调试的上方;)

error_reporting(E_ALL);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    相关资源
    最近更新 更多