处理因插入重复值而导致的唯一约束异常

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了处理因插入重复值而导致的唯一约束异常相关的知识,希望对你有一定的参考价值。

我有这个表(DDL):

CREATE TABLE corpname_skill
(
  id                                      SERIAL  NOT NULL
    CONSTRAINT corpname_skill_pkey
    PRIMARY KEY,
  guid                                    UUID,
  user_id                                 VARCHAR(50),
  user_strenght_area_name_1               VARCHAR(300),
  user_strenght_area_name_2               VARCHAR(300),
  user_strenght_area_name_3               VARCHAR(300),
  user_strenght_area_name_4               VARCHAR(300),
  user_development_area_name_1            VARCHAR(300),
  user_development_area_name_2            VARCHAR(300),
  user_development_area_name_3            VARCHAR(300),
  user_development_area_name_4            VARCHAR(300),
  line_manager_strenght_area_name_1       VARCHAR(300),
  line_manager_strenght_area_name_2       VARCHAR(300),
  line_manager_strenght_area_name_3       VARCHAR(300),
  line_manager_strenght_area_name_4       VARCHAR(300),
  line_manager_strenght_area_comment_1    TEXT    NOT NULL,
  line_manager_strenght_area_comment_2    TEXT    NOT NULL,
  line_manager_strenght_area_comment_3    TEXT    NOT NULL,
  line_manager_strenght_area_comment_4    TEXT    NOT NULL,
  line_manager_development_area_name_1    VARCHAR(300),
  line_manager_development_area_name_2    VARCHAR(300),
  line_manager_development_area_name_3    VARCHAR(300),
  line_manager_development_area_name_4    VARCHAR(300),
  line_manager_development_area_comment_1 TEXT,
  line_manager_development_area_comment_2 TEXT,
  line_manager_development_area_comment_3 TEXT,
  line_manager_development_area_comment_4 TEXT,
  line_manager_final_comment              TEXT,
  line_manager_step_status                VARCHAR(300),
  company_profile_id                         INTEGER NOT NULL
    CONSTRAINT corpname_skill_company_profile_id_key
    UNIQUE
    CONSTRAINT corpname_skill_company_profile_id_ae37e790_fk_corpname
    REFERENCES corpname_corpnameuserprofile
      DEFERRABLE INITIALLY DEFERRED,
  task_closing_date                       DATE
);

我正试图在那里插入:

INSERT INTO corpname_skill (
    guid, 
    user_id, 
    user_strenght_area_name_1, 
    user_strenght_area_name_2, 
    user_strenght_area_name_3, 
    user_strenght_area_name_4, 
    user_development_area_name_1, 
    user_development_area_name_2, 
    user_development_area_name_3, 
    line_manager_strenght_area_name_1, 
    line_manager_strenght_area_name_2, 
    line_manager_strenght_area_name_3, 
    line_manager_strenght_area_name_4, 
    line_manager_strenght_area_comment_1, 
    line_manager_strenght_area_comment_2, 
    line_manager_strenght_area_comment_3, 
    line_manager_strenght_area_comment_4, 
    line_manager_development_area_name_1, 
    line_manager_development_area_name_2, 
    line_manager_development_area_name_3, 
    line_manager_development_area_comment_1, 
    line_manager_development_area_comment_2, 
    line_manager_development_area_comment_3, 
    line_manager_final_comment, 
    line_manager_step_status, 
    task_closing_date, 
    company_profile_id
)
SELECT
    t.guid, 
    t.user_id, 
    t.user_strenght_area_name_1, 
    t.user_strenght_area_name_2, 
    t.user_strenght_area_name_3, 
    t.user_strenght_area_name_4, 
    t.user_development_area_name_1, 
    t.user_development_area_name_2, 
    t.user_development_area_name_3, 
    t.line_manager_strenght_area_name_1, 
    t.line_manager_strenght_area_name_2, 
    t.line_manager_strenght_area_name_3, 
    t.line_manager_strenght_area_name_4, 
    t.line_manager_strenght_area_comment_1, 
    t.line_manager_strenght_area_comment_2, 
    t.line_manager_strenght_area_comment_3, 
    t.line_manager_strenght_area_comment_4, 
    t.line_manager_development_area_name_1, 
    t.line_manager_development_area_name_2, 
    t.line_manager_development_area_name_3, 
    t.line_manager_development_area_comment_1, 
    t.line_manager_development_area_comment_2, 
    t.line_manager_development_area_comment_3, 
    t.line_manager_final_comment, 
    t.line_manager_step_status, 
    t.task_closing_date, 
    t.company_profile_id

FROM corpname_skill o
RIGHT JOIN corpname_skill_new t
ON t.company_profile_id = o.company_profile_id
WHERE o.company_profile_id IS NULL

但我遇到了一个独特的约束错误。

[23505] ERROR: duplicate key value violates unique constraint "corpname_skill_company_profile_id_key" Detail: Key (company_profile_id)=(256871) already exists.

我使用BEGIN...EXCEPTION...END;中描述的postgres docs块包装了sql语句:

BEGIN
    INSERT INTO corpname_skill (
        guid, 
        user_id, 
        user_strenght_area_name_1, 
        user_strenght_area_name_2, 
        user_strenght_area_name_3, 
        user_strenght_area_name_4, 
        user_development_area_name_1, 
        user_development_area_name_2, 
        user_development_area_name_3, 
        line_manager_strenght_area_name_1, 
        line_manager_strenght_area_name_2, 
        line_manager_strenght_area_name_3, 
        line_manager_strenght_area_name_4, 
        line_manager_strenght_area_comment_1, 
        line_manager_strenght_area_comment_2, 
        line_manager_strenght_area_comment_3, 
        line_manager_strenght_area_comment_4, 
        line_manager_development_area_name_1, 
        line_manager_development_area_name_2, 
        line_manager_development_area_name_3, 
        line_manager_development_area_comment_1, 
        line_manager_development_area_comment_2, 
        line_manager_development_area_comment_3, 
        line_manager_final_comment, 
        line_manager_step_status, 
        task_closing_date, 
        company_profile_id
    )
    SELECT
        t.guid, 
        t.user_id, 
        t.user_strenght_area_name_1, 
        t.user_strenght_area_name_2, 
        t.user_strenght_area_name_3, 
        t.user_strenght_area_name_4, 
        t.user_development_area_name_1, 
        t.user_development_area_name_2, 
        t.user_development_area_name_3, 
        t.line_manager_strenght_area_name_1, 
        t.line_manager_strenght_area_name_2, 
        t.line_manager_strenght_area_name_3, 
        t.line_manager_strenght_area_name_4, 
        t.line_manager_strenght_area_comment_1, 
        t.line_manager_strenght_area_comment_2, 
        t.line_manager_strenght_area_comment_3, 
        t.line_manager_strenght_area_comment_4, 
        t.line_manager_development_area_name_1, 
        t.line_manager_development_area_name_2, 
        t.line_manager_development_area_name_3, 
        t.line_manager_development_area_comment_1, 
        t.line_manager_development_area_comment_2, 
        t.line_manager_development_area_comment_3, 
        t.line_manager_final_comment, 
        t.line_manager_step_status, 
        t.task_closing_date, 
        t.company_profile_id

    FROM corpname_skill o
    RIGHT JOIN corpname_skill_new t
    ON t.company_profile_id = o.company_profile_id
    WHERE o.company_profile_id IS NULL
EXCEPTION 
    WHEN SQLSTATE '23505' THEN RAISE NOTICE 'skipped row';
END;

但是错误没有被捕获,我一直遇到同样的错误。我也尝试使用ON CONFLICT子句而不是这个,但是我遇到了语法错误。我想要实现的是一种跳过此错误并继续使用INSERT的方法,因此在这种情况下跳过导致错误的行。

对此有何帮助?

答案

你似乎把SQL statement BEGIN(开始交易)与BEGIN and EXCEPTION keywordsblock-structured procedural language PL/pgSQL混淆了。

普通SQL中没有EXCEPTION命令。

为了处理INSERT操作中的重复键错误,ON CONFLICT子句将是您的最佳选择。基本语法:

INSERT ... ON CONFLICT DO NOTHING;

细节:

以上是关于处理因插入重复值而导致的唯一约束异常的主要内容,如果未能解决你的问题,请参考以下文章

二十异常捕获及处理详解

“ORA-00001:违反了唯一约束”,即使使用异常

数据库唯一性约束异常插入处理

休眠约束违反异常挂起sql server

如何在 SQLiteConstraintException 上捕获列名唯一约束失败

mysql如何避免主键或者唯一索引重复导致的插入失败问题