我对ON DUPLICATE KEY UPDATE
的作用有点困惑。我正在寻找的东西将检查INSERT INTO
SQL命令,如果任何行是重复的,则不更新该行。现在,如果该行中的任何内容不重复(但有些内容),我想用更新的信息替换该行。
这是否可以使用基本的MYSQL,或者我将首先必须提取所有数据,然后交叉检查它。我宁愿不这样做,因为我所要做的就是每天缓存一次相当数量的数据。
"INSERT INTO years (date,year,venue,city,state,country,showid) VALUES (?,?,?,?,?,?,?)"
答案 0 :(得分:3)
ON DUPLICATE KEY UPDATE
只是在重复键的情况下执行您提供给它的SET
语句。它不会比较单个列值,只会更新不同的列值。只要您具有定义为UNIQUE KEY
或PRIMARY KEY
的正确列,它听起来就像您想要做的那样。
但是,我通常做的是运行插入,然后捕获错误并在需要时执行不同的操作。如果存在重复,这会产生2个查询的缺点,但在我看来,它更易于维护。
示例:
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare('INSERT INTO some_tbl (col1,col2,col3) VALUES (?,?,?)');
$values = array('Col 1 value','Col 2 Value', 'Col 3 Value');
try {
$db->execute($values);
} catch (PDOException $e) {
if($e->getCode() == 23000){
// dupe key do some other action whether update or otherwise
} else {
// rethrow non dupe errors
throw $e;
}
}
答案 1 :(得分:1)
正如一些人已经建议的那样,您需要做的第一件事就是定义什么是重复行。这是通过设置UNIQUE索引来完成的。例如,如果您认为表中没有重复的场地,则应在场地上设置UNIQUE索引。如果它是场地和日期的组合(基本上是说 - 你不能在同一个日期在同一个地方有两个事件),那么你将定义一个复合的UNIQUE索引,它看起来像UNIQUE(场地,日期)。
当你有这样的设置。您可以开始使用ON DUPLICATE KEY UPDATE:如果您输入的数据将与现有的复合唯一键匹配 - 您将只更新相关列。如果没有 - 您将添加一个新的。该语句的语法是:
INSERT INTO table (col1, col2, col3) VALUES(?, ?, ?) ON DUPLICATE KEY UPDATE SET col3 = VALUE(col3);
如果没有像之前那样的唯一键,这将插入一个新行(假设唯一键是UNIQUE(col1,col2) - 所以之前没有col1和col2对)。如果表中存在一对col1和col2,它将用您提供的值替换col3值。
现在,谈到您的示例,看起来您需要在所有列上使用复合UNIQUE索引。我不是专家,但对我而言,这看起来不是最好的做法:)
因此,我建议稍微重新考虑一下你的表结构:
答案 2 :(得分:0)
您可以在数据的每一列上创建UNIQUE INDEX。如果新行的所有列都与现有行中的所有列完全相同,那么这将使得它会抛出重复的错误,这就是你想要的。
ALTER TABLE TABLE ADD UNIQUE uniqueconstraintname(col1,col2,...);
W3Schools on Unique Constraints:http://www.w3schools.com/sql/sql_unique.asp
答案 3 :(得分:0)
如果指定ON DUPLICATE KEY UPDATE,则插入一行 会导致UNIQUE索引或PRIMARY KEY中的重复值 执行旧行的更新。 例如,如果列a声明为UNIQUE并包含该值 1,以下两个陈述具有相同的效果:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
UPDATE表SET c = c + 1 WHERE a = 1;
答案 4 :(得分:0)
之前我误解了你的问题,我编辑了这篇文章
当你尝试做两件不同的事情时,你必须将它分成INSERT语句和UPDATE语句。并且要使UPDATE语句起作用,您至少需要一个键,然后检查该行以查看是否有任何值。
您可以检查行的存在,只有在它不存在时才插入。
INSERT声明
INSERT INTO tbl_name (key, col1, col2, col3)
SELECT keyval, val1, val2, val3
FROM dual
WHERE NOT EXISTS
(SELECT key, col1, col2, col3
FROM tbl_name
WHERE key = keyval AND col1 = val1 AND col2 = val2 AND col3 = val2)
dual只是一个占位符表,允许您插入所需的值并允许WHERE子句
更新声明
UPDATE tbl_name
SET col1 = val1
col2 = val2
col3 = val3
WHERE key = keyval AND
(col1 <> val1 OR col2 <> val2 OR col3 <> val3)