使用INSERT ON CONFLICT在多个列上碰撞唯一约束,其中一个列可能为null

时间:2017-11-08 17:06:17

标签: sql postgresql unique-key unique-index

晚上好,

说我有一张桌子,

CREATE TABLE test(
col_1 integer,
col_2 integer,
col_3 integer,
CONSTRAINT test_uk UNIQUE (col_1, col_2, col_3));

插入两行;

INSERT INTO test (col_1 ,col_2 ,col_3) VALUES (1,2,NULL),(1,2,NULL);

这不会引发错误,因为postgres将空值视为不相等。 我可以在这三个列中添加哪些约束,我可以使用

进行更新
INSERT...... ON CONFLICT ... DO UPDATE...;

目前查询不会因上述情况而发生冲突,因为如上所述,空值不会被视为相等。

提前致谢。

1 个答案:

答案 0 :(得分:0)

不是很优雅,但你可以将NULL合并到一些" reserved"值,例如0或-1。随着"保留"我的意思是你知道它不会成为潜在列值的一部分。

switch effect {
            //NO BG ONLY EFFECTS
        case let (bg,effect) where (bg == 0 && effect == 0):
             print(" NO BG & none")
        case let (bg,effect) where (bg == 0 && effect == 1):
            print(" NO BG & robot")
        case let (bg,effect) where (bg == 0 && effect == 2):
            print(" NO BG & monkey")
        case let (bg,effect) where (bg == 0 && effect == 3):
            print(" NO BG & bee")
        case let (bg,effect) where (bg == 0 && effect == 4):
            print(" NO BG & elephant")
        case let (bg,effect) where (bg == 0 && effect == 5):
            print(" NO BG & mask")
        case let (bg,effect) where (bg == 0 && effect == 6):
            print(" NO BG & ghost")
        case let (bg,effect) where (bg == 0 && effect == 7):
            print(" NO BG & speed")

            //BG WIND & EFFECT CHANGED
        case let (bg,effect) where (bg == 1 && effect == 0):
            print("wind & none")
        case let (bg,effect) where (bg == 1 && effect == 1):
            print("wind & robot")
        case let (bg,effect) where (bg == 1 && effect == 2):
            print("wind & monkey")
        case let (bg,effect) where (bg == 1 && effect == 3):
            print("wind & bee")
        case let (bg,effect) where (bg == 1 && effect == 4):
            print("wind & elephant")
        case let (bg,effect) where (bg == 1 && effect == 5):
            print("wind & mask")
        case let (bg,effect) where (bg == 1 && effect == 6):
            print("wind & ghost")
        case let (bg,effect) where (bg == 1 && effect == 7):
            print("wind & speed")

            //BG CITY & EFFECT CHANGED
        case let (bg,effect) where (bg == 2 && effect == 0):
            print("city & none")
        case let (bg,effect) where (bg == 2 && effect == 1):
            print("city & robot")
        case let (bg,effect) where (bg == 2 && effect == 2):
            print("city & monkey")
        case let (bg,effect) where (bg == 2 && effect == 3):
            print("city & bee")
        case let (bg,effect) where (bg == 2 && effect == 4):
            print("city & elephant")
        case let (bg,effect) where (bg == 2 && effect == 5):
            print("city & mask")
        case let (bg,effect) where (bg == 2 && effect == 6):
            print("city & ghost")
        case let (bg,effect) where (bg == 2 && effect == 7):
            print("city & speed")

           // AND THE LIST CONTINUES...