SQL语法,用于在更新之前检查重复项(不是重复密钥更新)

时间:2018-10-24 22:32:40

标签: mysql sql

我有一个句法问题,如果两个UPDATE字段匹配,则尝试non key。 -INSERT(如果不匹配)。

让我首先说我有一个有效查询,其中涉及一个SELECT和一个ON DUPLICATE KEY UPDATE。现在我很好奇,可以做不同的事情吗?

出于好奇,我以不需要primary key的方式尝试此操作。这真的只是一个实验,看是否可以完成。

我想要的是 like ON DUPLICATE KEY UPDATE-但是:

  1. 假装我不认识key
  2. 假装我无法获得带有SELECT的钥匙

这是我拥有的数据结构:

+--------------------------------------------------------------------------+ 
|   id   |    contractor_id    |    email_type_id    |    email_address    |
+--------------------------------------------------------------------------+

表创建:

CREATE TABLE `email_list` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `contractor_id` int(11) NOT NULL,
  `email_type_id` int(11) NOT NULL,
  `email_address` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

现在我要尝试执行的没有选择没有ON DUPLICATE KEY UPDATE 的操作是-如果contractor_id email_type_id被匹配-UPDATE email_address –否则INSERT

如果已经尝试过此操作-(我知道我违反了自己的“不选择”规则):

IF EXISTS (SELECT * FROM email_list WHERE contractor_id = 1166)
    UPDATE email_list SET (email_address='herky_jerky@snailmail.com')
    WHERE contractor_id = 1166 AND email_type_id = 4
ELSE
    INSERT INTO email_list VALUES (
     contractor_id = 1166, 
     email_type_id = 4, 
     email_address = 'herky_jerky@snailmail.com');

我了解为什么不起作用..我只是不知道它的解决方法-使用IF - ELSE语句也感觉有些笨拙。另外,我也不想使用SELECT,于是我想到只使用IF,例如:

UPDATE email_list SET email_address = 'herky@jerky.com' 
WHERE contractor_id = 1166 AND email_type_id = 4
IF @@ROWCOUNT=0
    INSERT INTO email_list VALUES (
    contractor_id = 1166, 
    email_type_id = 4, 
    email_address = 'herky@jerky.com');

但是我不明白为什么那个不起作用。这只是一种练习,以查看这种查询的创造力。我认为我的两个想法都是可行的-任何人都可以找到一个解决方案来使其有效吗?

我也很乐意看到其他更有创意的方式来尝试我要问的问题!

1 个答案:

答案 0 :(得分:1)

我将使用UPDATE来实现此目的,然后再测试ROW_COUNT(),如果没有更新任何行,则INSERT

drop table if exists t;

create table t (id int, x int, y int, str varchar(255));

insert into t (id, x, y, str) values (1, 2, 3, 'foo');

select * from t;

update t set str = 'bar'
where x = 2 and y = 3;

insert into t (id, x, y, str)
select 1, 2, 3, 'inserted'
from dual
where row_count() = 0;

select * from t;

update t set str = 'baz'
where x = 20 and y = 30;

insert into t (id, x, y, str)
select 10, 20, 30, 'baz'
from dual
where row_count() = 0;

select * from t;

drop table t;

您可以在此处查看它的运行情况:https://rextester.com/FRFTE79537

这里的想法是先执行UPDATE,然后执行INSERT ... SELECT,其中SELECT仅返回行,如果 ROW_COUNT() = 0是是正确的,只有在UPDATE与任何行都不匹配的情况下才是正确的。