【问题标题】:Adapt ON CONFLICT clause to new unique index?使 ON CONFLICT 子句适应新的唯一索引?
【发布时间】:2019-10-10 05:10:29
【问题描述】:

我想为现有表添加一个额外的唯一约束。 This 和其他答案说使用 sqlite 是不可能的,并建议创建一个唯一索引:

ALTER TABLE example ADD COLUMN new_unique TEXT;
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);

这似乎有效。但是,我遇到了UPSERTs 的问题:

INSERT INTO example (foo, old_unique, new_unique) VALUES ('foo', 'old', 'new') ON CONFLICT(old_unique, new_unique) DO UPDATE SET foo='foo';

这给出了一个错误:

ON CONFLICT cause does not match any PRIMARY KEY or UNIQUE constraint

有什么办法可以调整上述语句的ON CONFLICT 子句以使用新的“约束”?

我尝试使用new_unique_index,但无济于事。如果不可能,是否有任何替代方法可以创建具有新唯一约束的新表并将旧表中的值复制到新约束列为 NULL 的新表中?这会很麻烦。我想我可以创建一个新表,其中包含前者的所有列,除了旧的唯一列,加上新的唯一列,并以某种方式链接它们,但这听起来很乱,我不知道如何继续。

最小可重现示例:

CREATE TABLE example (foo TEXT, old_unique TEXT, UNIQUE(old_unique));
ALTER TABLE example ADD COLUMN new_unique TEXT;
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
INSERT INTO example (foo, old_unique, new_unique) VALUES ('foo', 'old', 'new') ON CONFLICT(old_unique, new_unique) DO UPDATE SET foo='foo';

【问题讨论】:

    标签: sqlite


    【解决方案1】:

    有什么方法可以调整上述语句的 ON CONFLICT 子句以使用新的“约束”?

    (old_unique, new_unique) 不是一个可能的约束目标,因为没有结合两列的索引,每一个都是一个单独的约束(所以你可以使用一个或另一个,因为我的理解是你被限制在一个一个 UPSERT 子句和一个冲突目标)。

    如果不是:-

    CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
    

    你用过

    CREATE UNIQUE INDEX new_unique_index ON example(old_unique,new_unique);
    

    然后以下将起作用:-

    INSERT INTO example (foo,old_unique,new_unique) VALUES('foo','old','new') ON CONFLICT (old_unique,new_unique) DO UPDATE SET foo = 'foo'; 
    

    (至少不会因为没有覆盖给定冲突目标的主键或索引而被拒绝)。

    如果不可能,是否有任何替代方法可以创建具有新唯一约束的新表并将旧表中的值复制到新约束列为 NULL 的新表中?这将是繁重的

    这并不是真正的负担,例如你可以使用:-

    CREATE TABLE IF NOT EXISTS temp_example (foo, old_unique,new_unique, UNIQUE(old_unique,new_unique));
    INSERT INTO temp_example SELECT *,null FROM example;
    ALTER TABLE example RENAME TO old_example;
    ALTER TABLE temp_example RENAME TO example;
    DROP TABLE If EXISTS old_example;
    
    • 即由于您要添加一列并且它将是最后一列,因此无需对列名进行编码。

    【讨论】:

    • 索引创建和上面的 UPSERT 工作正常。但是,在使用实际表时,我无法使 UPSERT 工作 - 这些值没有被插入到新列中。我无法在我提供的最小示例中重现这一点。我最终按照建议创建了一个新表。谢谢。
    猜你喜欢
    • 2016-12-21
    • 2020-06-02
    • 2016-08-07
    • 2017-11-18
    • 2016-05-11
    • 1970-01-01
    • 2023-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多