On Duplicate Key Update与insert相同

时间:2013-01-17 16:21:17

标签: mysql on-duplicate-key

我已经四处寻找,但没有找到是否可能。

我有这个MySQL查询:

INSERT INTO table (id,a,b,c,d,e,f,g) VALUES (1,2,3,4,5,6,7,8)

字段ID具有“唯一索引”,因此不能有两个。现在,如果数据库中已存在相同的ID,我想更新它。但我真的必须再次指定所有这些字段,例如:

INSERT INTO table (id,a,b,c,d,e,f,g) VALUES (1,2,3,4,5,6,7,8) 
ON DUPLICATE KEY UPDATE a=2,b=3,c=4,d=5,e=6,f=7,g=8

或者:

INSERT INTO table (id,a,b,c,d,e,f,g) VALUES (1,2,3,4,5,6,7,8) 
ON DUPLICATE KEY UPDATE a=VALUES(a),b=VALUES(b),c=VALUES(c),d=VALUES(d),e=VALUES(e),f=VALUES(f),g=VALUES(g)

我已经在插入中指定了所有内容......

额外的注意事项,我想使用这些工作来获取ID!

id=LAST_INSERT_ID(id)

我希望有人能告诉我最有效的方法。

8 个答案:

答案 0 :(得分:69)

给出UPDATE语句,以便可以将旧字段更新为新值。如果您的旧值与新值相同,为什么在任何情况下都需要更新它?

例如。如果您的ag列已经设置为28;没有必要重新更新它。

或者,您可以使用:

INSERT INTO table (id,a,b,c,d,e,f,g)
VALUES (1,2,3,4,5,6,7,8) 
ON DUPLICATE KEY
    UPDATE a=a, b=b, c=c, d=d, e=e, f=f, g=g;

id获取LAST_INSERT_ID;你需要指定你正在使用的后端应用程序。

对于LuaSQL,conn:getlastautoid()获取值。

答案 1 :(得分:39)

SQL的MySQL特定扩展可能是您想要的 - REPLACE INTO

然而,它与“ON DUPLICATE UPDATE”

的工作方式完全不同
  1. 它删除与新行冲突的旧行,然后插入新行。只要您没有表上的主键就可以了,但如果您这样做,那么如果有任何其他表引用该主键

  2. 您无法引用旧行中的值,因此您无法执行等效的

    INSERT INTO mytable (id, a, b, c) values ( 1, 2, 3, 4) 
    ON DUPLICATE KEY UPDATE
    id=1, a=2, b=3, c=c + 1;
    
  3.   

    我想用这个方法来获取ID!

    这应该有用 - 只要你的主键是自动递增的,last_insert_id()就应该有正确的值。

    但是正如我所说,如果您在其他表中实际使用该主键,REPLACE INTO可能不会被您接受,因为它会删除通过唯一键冲突的旧行。

    其他人suggested before你可以通过以下方式减少一些打字:

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

答案 2 :(得分:21)

Here is a solution to your problem:

I've tried to solve problem like yours & I want to suggest to test from simple aspect.

Follow these steps: Learn from simple solution.

Step 1: Create a table schema using this SQL Query:

CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) NOT NULL,
  `password` varchar(32) NOT NULL,
  `status` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `no_duplicate` (`username`,`password`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

A table <code>user</code> with data

Step 2: Create an index of two columns to prevent duplicate data using following SQL Query:

ALTER TABLE `user` ADD INDEX no_duplicate (`username`, `password`);

or, Create an index of two column from GUI as follows: Create index from GUI Select columns to create index Indexes of table <code>user</code>

Step 3: Update if exist, insert if not using following queries:

INSERT INTO `user`(`username`, `password`) VALUES ('ersks','Nepal') ON DUPLICATE KEY UPDATE `username`='master',`password`='Nepal';

INSERT INTO `user`(`username`, `password`) VALUES ('master','Nepal') ON DUPLICATE KEY UPDATE `username`='ersks',`password`='Nepal';

Table <code>user</code> after running above query

答案 3 :(得分:20)

没有其他办法,我必须指明一切两次。第一个是插入,第二个是更新案例。

答案 4 :(得分:7)

如果您能够使用脚本语言来准备SQL查询,则可以使用SET而不是(a,b,c) VALUES(a,b,c)重复使用field = value对。

PHP的一个例子:

$pairs = "a=$a,b=$b,c=$c";
$query = "INSERT INTO $table SET $pairs ON DUPLICATE KEY UPDATE $pairs";

示例表:

CREATE TABLE IF NOT EXISTS `tester` (
  `a` int(11) NOT NULL,
  `b` varchar(50) NOT NULL,
  `c` text NOT NULL,
  UNIQUE KEY `a` (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

答案 5 :(得分:4)

您可能需要考虑使用REPLACE INTO语法,但要注意,在重复的PRIMARY / UNIQUE键上, DELETES 行, INSERTS 一个新的

您无需重新指定所有字段。但是,您应该考虑可能的性能降低(取决于您的表格设计)。

注意事项:

  • 如果您有AUTO_INCREMENT主键,则会给它一个新的
  • 索引可能需要更新

答案 6 :(得分:1)

我知道已经晚了,但我希望有人会对此答案有所帮助

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6)
ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

您可以在此处阅读以下教程:

  

https://mariadb.com/kb/en/library/insert-on-duplicate-key-update/

     

http://www.mysqltutorial.org/mysql-insert-or-update-on-duplicate-key-update/

答案 7 :(得分:-7)

你可以在这种情况下使用insert ignore,如果它获得重复记录,它将被忽略 INSERT IGNORE   ......; - 没有ON DUPLICATE KEY