这个SQL查询怎么可能将重复值INSERT到数据库中?

时间:2012-02-17 15:19:19

标签: sql ruby-on-rails ruby postgresql indexing

背景:这适用于Ruby on Rails Web应用程序。我有一份后台工作,从Facebook下载最近的帖子并将它们插入数据库。我正在使用手工编写的SQL来提高性能。 RDBMS是PostgreSQL(在Heroku上)。

该表称为“帖子”。我对posts.uidposts.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 个答案:

答案 0 :(得分:2)

您的选择查询将返回重复的行。

答案 1 :(得分:1)

检查空值。

我假设唯一索引"index_posts_on_uid_and_contact_id"不是PK,因此它将接受空值。

上的其中一个字段
SELECT * FROM posts 
           WHERE posts.uid = t.uid 
           AND posts.contact_id = contacts.id

query为null,exists将返回false,并且可能会插入重复的数据。

另外,我会select 1代替select *。我认为它更好

我愿意

WHERE (contacts.fb_id = t.fb_id) and (t.uid is not null) and  (contacts.id is not null)