【问题标题】:Postgres UPSERT syntax confusionPostgres UPSERT 语法混乱
【发布时间】:2017-08-11 22:37:28
【问题描述】:

我有一个有 2 列的表: 频道文本 rowid 整数主键

我在频道中加入了索引 在 mytable 上创建唯一索引 channels_index (lower(channels))

这样 VisitToronto 将与 visittoronto 发生冲突

一切顺利,冲突开始了。 错误:重复键值违反唯一约束“channels_index” DETAIL: Key (lower(words))=(hello world) 已经存在。

我无法弄清楚捕获此冲突的语法。 ON CONFLICT 频道不起作用 ON CONFLICT ON CONSTRAINT channels_index 不起作用

我得到的最接近的是: 错误:没有符合 ON CONFLICT 规范的唯一或排除约束

任何方向都将不胜感激。

TIA

【问题讨论】:

    标签: postgresql upsert


    【解决方案1】:

    使用索引表达式,即lower(channels):

    insert into my_table (channels) values
    ('VisitToronto');
    
    insert into my_table (channels) 
    values ('visittoronto')
    on conflict (lower(channels)) do 
    update set channels = excluded.channels;
    
    select *
    from my_table;
    
     id |   channels   
    ----+--------------
      1 | visittoronto
    (1 row)
    

    您无法使用约束,因为索引位于表达式上。在 Postgres 无法创建约束的情况下:

    alter table my_table add constraint channels_unique unique using index channels_index;
    
    ERROR:  index "channels_index" contains expressions
    LINE 1: alter table my_table add constraint channels_unique unique u...
                                     ^
    DETAIL:  Cannot create a primary key or unique constraint using such an index.
    

    【讨论】:

    • 非常感谢。我现在也理解了 Docs 的内容也好一点。有没有办法在不进行更新的情况下返回 channels_rowid?如果不是那没关系,我真的不在乎数据库中的哪个版本,主要是自学。我在更新语句之后使用'returning channels_rowid',该语句为插入和更新都返回,但如果我“不做任何事情”它不会返回,如果我使用 SELECT 我会收到错误
    • 很遗憾,您无法从do nothing 返回任何内容,因为没有任何行受到影响。你需要一个函数来完成这个。
    猜你喜欢
    • 1970-01-01
    • 2017-06-11
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    相关资源
    最近更新 更多