Синтаксис SQL для проверки дубликатов перед обновлением (не DUPLICATE KEY UPDATE) - PullRequest
0 голосов
/ 25 октября 2018

У меня есть синтаксический вопрос с попыткой UPDATE, если 2 non key поля совпадают.- INSERT если не совпадает.

Позвольте мне начать с того, что у меня есть рабочий запрос , который включает SELECT с ON DUPLICATE KEY UPDATE.Теперь мне просто любопытно, может ли это быть сделано по-другому?

Из чистого любопытства я пытаюсь сделать это так, чтобы не потребовалось primary key.Это действительно всего лишь эксперимент, чтобы увидеть, можно ли это сделать.

То, что я хочу, это как 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 is - Если contractor_id и email_type_id совпадают - UPDATE the email_address - иначе INSERT.

Если попытались это - (Я знаю, что нарушаю свое собственное правило отсутствия SELECT):

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 голосов
/ 25 октября 2018

Я бы реализовал это, используя 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 имеет значение true, иэто верно только в том случае, если UPDATE не соответствует ни одной строке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...