Russian Qt Forum
Март 29, 2024, 10:19 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: PostgreSQL автоматическое игнорирование добавления одинаковых строк  (Прочитано 8681 раз)
Viktor
Гость
« : Июль 14, 2016, 14:27 »

Пытаюсь сделать так, что бы запрос INSERT не добавлял строки с одинаковыми данными. Наткнулся на такую команду как INSERT ....... ON CONFLICT.

Моя задача сделать так: если все столбцы одинаковые, кроме идентификационного номера, то запись просто не добавляется. Сделал следующим образом:

INSERT INTO "Apartments"
("name", "kvm", "rooms", "etaj", "date_add", "date_update")
VALUES
('Новый дом', 26, 3, 4, '2016-06-29 12:12:43', '2016-07-11 10:50:37')
ON CONFLICT ("name", "kvm", "rooms", "etaj", "date_add", "date_update") DO NOTHING;

не не вышло, может кто подскажет в чём тут проблема?
Записан
PimenS
Крякер
****
Offline Offline

Сообщений: 371


Просмотр профиля
« Ответ #1 : Июль 14, 2016, 14:41 »

Насколько я понял из документации conflict_target должны быть определены как UNIQUE.

По крайней мере у меня так работает.

Код:
CREATE TABLE n_catalogs.slist_search_text
(
  search_text character varying NOT NULL, -- Строка поиска
  search_quantity bigint NOT NULL, -- Количество
  search_type integer NOT NULL, -- Тип поиска
  CONSTRAINT slist_search_text_text_type_pkey PRIMARY KEY (search_text, search_type)
);

Код:
q.prepare("INSERT INTO n_catalogs.slist_search_text AS old (search_text, search_quantity, search_type) "
              "VALUES (?, 1, ?) ON CONFLICT (search_text, search_type) "
              "DO UPDATE SET search_quantity = old.search_quantity + 1;");
« Последнее редактирование: Июль 14, 2016, 14:45 от PimenS » Записан
Viktor
Гость
« Ответ #2 : Июль 14, 2016, 15:32 »

Насколько я понял из документации conflict_target должны быть определены как UNIQUE.

По крайней мере у меня так работает.

Код:
q.prepare("INSERT INTO n_catalogs.slist_search_text AS old (search_text, search_quantity, search_type) "
              "VALUES (?, 1, ?) ON CONFLICT (search_text, search_type) "
              "DO UPDATE SET search_quantity = old.search_quantity + 1;");

Я верно понял, что ON CONFLICT (search_text, search_type) сравнивает поля search_text, search_type и если они одинаковые, то добавление записи игнорируется?
Записан
PimenS
Крякер
****
Offline Offline

Сообщений: 371


Просмотр профиля
« Ответ #3 : Июль 14, 2016, 15:56 »

В моем случае просто выполняется UPDATE, если сделать DO NOTHING, то запись игнорируется.

Ну т.е если есть например таблица

Код:
CREATE TABLE test
(
  stext character varying NOT NULL,
  squantity bigint NOT NULL,
  CONSTRAINT text_pkey PRIMARY KEY (stext, squantity)
);

Добавим туда данные

Код:
INSERT INTO test VALUES('A', 1), ('B', 1);

Если использовать ON CONFLICT

Код:
INSERT INTO test(stext, squantity) VALUES('A', 1) ON CONFLICT (stext, squantity) DO NOTHING;

То такая запись не добавится. А вот если

Код:
INSERT INTO test(stext, squantity) VALUES('A', 2) ON CONFLICT (stext, squantity) DO NOTHING;

то запишется.

ЗЫ. Не сравниваются search_text с search_type. Ищутся записи search_text, search_type и если в базе уже есть такая пара, то тогда и срабатывает исключение.
« Последнее редактирование: Июль 14, 2016, 16:01 от PimenS » Записан
Viktor
Гость
« Ответ #4 : Июль 14, 2016, 17:12 »

Большое спасибо! Всё получилось! Дело было ещё в том, что нужно было указать в настройках таблицы, какие столбцы являются уникальными!
Записан
PimenS
Крякер
****
Offline Offline

Сообщений: 371


Просмотр профиля
« Ответ #5 : Июль 14, 2016, 17:41 »

Так об этом я и говорил

Цитировать
conflict_target должны быть определены как UNIQUE.
Записан
Viktor
Гость
« Ответ #6 : Июль 14, 2016, 17:46 »

Так об этом я и говорил

Цитировать
conflict_target должны быть определены как UNIQUE.

да, просто я не сразу понял, я с этим впервые сталкиваюсь)
Записан
PimenS
Крякер
****
Offline Offline

Сообщений: 371


Просмотр профиля
« Ответ #7 : Июль 14, 2016, 17:59 »

Ну это у всех так. ON CONFLICT только в 9.5 появилось. Мало кто сразу на новый релиз переходит. А плюшка очень полезная.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.048 секунд. Запросов: 22.