SQL防止重复INSERT

时间:2015-11-18 07:18:49

标签: php mysql curl

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

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

我如何防止重复,只更新缺少的信息或与$ var值不同的信息?

我想做什么

如果新值不是旧值,则使用旧值,否则使用新值;

    $prep_stmt = "SELECT * FROM members WHERE record NOT LIKE record=? ";
$stmt = $mysqli->prepare($prep_stmt);

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

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

                                        VALUES (?)")) 

        {
        $insert_stmt->bind_param('s',$repStartDate);

    if (! $insert_stmt->execute()) {header('Location: ../error.php?err=Registration failure: INSERT');}
        }
}
}

3 个答案:

答案 0 :(得分:2)

如果你不想更新,那么你可以使用Insert Ignore,如下所示。

mysql> SELECT * FROM visit;
Empty set (0.00 sec)

mysql> INSERT IGNORE INTO visit (user_id, total_visit) VALUES (32, 1);
Query OK, 1 row affected (0.01 sec)

mysql> INSERT IGNORE INTO visit (user_id, total_visit) VALUES (32, 1);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM visit;
+----+---------+-------------+
| id | user_id | total_visit |
+----+---------+-------------+
|  1 |      32 | 1           |
+----+---------+-------------+
1 row in set (0.00 sec)

如果想要更新,则该记录存在时,您可以使用下面的On Duplicate Key Update

mysql> INSERT IGNORE INTO visit (user_id, total_visit) VALUES (32, 1) ON DUPLICATE KEY UPDATE total_visit = total_visit + VALUES(total_visit);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM visit;
+----+---------+-------------+
| id | user_id | total_visit |
+----+---------+-------------+
|  1 |      32 | 1           |
+----+---------+-------------+
1 row in set (0.00 sec)

mysql> INSERT IGNORE INTO visit (user_id, total_visit) VALUES (32, 1) ON DUPLICATE KEY UPDATE total_visit = total_visit + VALUES(total_visit);
Query OK, 2 rows affected (0.00 sec)

mysql> SELECT * FROM visit;
+----+---------+-------------+
| id | user_id | total_visit |
+----+---------+-------------+
|  1 |      32 | 2           |
+----+---------+-------------+
1 row in set (0.00 sec)

FULL EXAMPLE is here

答案 1 :(得分:1)

使用replace而不是insert:

REPLACE INTO members (...) VALUES (...)

如果它是新数据,这将创建一个新行(如insert),如果该行是表现有条目的副本,则会更新现有数据。

通过查看主键字段和唯一键可以找到重复项。因此,如果您的数据数据是双重的,例如用户名匹配,然后使用户名成为唯一索引或主键。

可在https://dev.mysql.com/doc/refman/5.7/en/replace.html

找到更多文档

P.S。:INSERT ON DUPLICATE KEY UPDATE也是一个有效的解决方案。

答案 2 :(得分:0)

我看不出这个最小的例子无法解决的问题的哪个部分:

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table (id INT AUTO_INCREMENT PRIMARY KEY,constant CHAR(1) NOT NULL);

INSERT INTO my_table VALUES (1,'a'),(2,'b'),(3,'a');

INSERT INTO my_table (id,constant) VALUES(1,'b') ON DUPLICATE KEY UPDATE constant = VALUES(constant);

INSERT INTO my_table (id,constant) VALUES(4,'a') ON DUPLICATE KEY UPDATE constant = VALUES(constant);


SELECT * FROM my_table;
+----+----------+
| id | constant |
+----+----------+
|  1 | b        |
|  2 | b        |
|  3 | a        |
|  4 | a        |
+----+----------+