Как этот SQL-запрос может ВСТАВИТЬ дубликаты значений в базу данных? - PullRequest
0 голосов
/ 17 февраля 2012

Справочная информация: это для веб-приложения Ruby on Rails. У меня есть фоновая работа, которая загружает последние сообщения из Facebook и вставляет их в базу данных. Я использую ручной код SQL для производительности. СУБД - это PostgreSQL (на Heroku).

Таблица называется "сообщения". У меня есть уникальный индекс по комбинации posts.uid и posts.contact_id. В SQL я использую условие WHERE для фильтрации uid - contact_id комбинаций, которые уже есть в таблице, но даже в этом случае я получаю следующую ошибку:

ActiveRecord::RecordNotUnique: PGError: ERROR: duplicate key value violates unique constraint "index_posts_on_uid_and_contact_id"

Без лишних слов, вот (динамический) SQL:

INSERT INTO posts 
(message,contact_id,date,uid,created_at,updated_at,source,is_event)
SELECT  
    t.msg,
    contacts.id, 
    t.date,
    t.uid,
    CURRENT_TIMESTAMP,
    CURRENT_TIMESTAMP,'facebook',
    FALSE
FROM contacts, 
(VALUES #{posts.map { |post| "(E'#{post['message'].escape_singles}','#
 {post['uid']}',DATE '#{format_date(post['time'])}',#{post['status_id']})" }.join(", ")}) AS      
 t (msg,fb_id,date,uid)
WHERE contacts.fb_id = t.fb_id 
AND (NOT EXISTS (
           SELECT * FROM posts 
           WHERE posts.uid = t.uid 
           AND posts.contact_id = contacts.id));

Разве условие NOT EXISTS не должно препятствовать этому?

Ответы [ 2 ]

2 голосов
/ 17 февраля 2012

Ваш запрос на выборку возвращает повторяющиеся строки.

1 голос
/ 17 февраля 2012

проверка на нулевые значения.

Я предполагаю, что уникальный индекс "index_posts_on_uid_and_contact_id" не является PK, поэтому он будет принимать нули. Если одно из полей на

SELECT * FROM posts 
           WHERE posts.uid = t.uid 
           AND posts.contact_id = contacts.id

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

Кроме того, я бы сделал select 1 вместо select *. Я думаю, что лучше

Я бы сделал

WHERE (contacts.fb_id = t.fb_id) and (t.uid is not null) and  (contacts.id is not null)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...