当前位置: 首页 > 知识库问答 >
问题:

在插入查询中不处理外键冲突SQL

公孙锋
2023-03-14

在迁移程序中,我对表_1执行插入查询,其定义如下:

CREATE TABLE table_1
(
    col1 character varying(4)  COLLATE pg_catalog."default" NOT NULL,
    col2 character varying(10) COLLATE pg_catalog."default" NOT NULL,
    col3 character varying(10) COLLATE pg_catalog."default" NOT NULL,
    col4 character varying(40) COLLATE pg_catalog."default" NOT NULL,
    col5 date NOT NULL,
    col6 date NOT NULL,

    CONSTRAINT table_1_pkey 
        PRIMARY KEY (col1, col2, col3, col4, col5, col6),

    CONSTRAINT table_2_fkey FOREIGN KEY (col4)
        REFERENCES table_2 (col1) MATCH SIMPLE
            ON UPDATE NO ACTION
            ON DELETE NO ACTION,
    CONSTRAINT table_3_fkey FOREIGN KEY (col3)
        REFERENCES table_3(col1) MATCH SIMPLE
            ON UPDATE NO ACTION
            ON DELETE NO ACTION
            NOT VALID
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

现在,当我尝试插入此表时,我得到以下错误:

事务错误中的错误:在表"table_1"上插入或更新违反外键约束"table_2_fkey"

我尝试在以下表单中执行插入查询:

INSERT INTO table_1(col1, col2, col3, col4, col5, col6) 
VALUES 
(col1_value1, col2_value1, col3_value1, col4_value1, col5_value1, col6_value1),
(col1_value2, col2_value2, col3_value2, col4_value2, col5_value2, col6_value2),
(col1_value3, col2_value3, col3_value3, col4_value3, col5_value3, col6_value3)
ON CONFLICT (col1, col2, col3, col4, col5, col6) DO NOTHING;

有没有办法防止违反外键约束(跳过它们)?

类似on违规什么都不做

注意:它不违反第二个外键约束,因为我将此表(table_2)中的数据填充为我试图填充到table_1的行(用于规范化)。table_2是一个早先存在的表,我在另一个程序中填充了那里的行,所以那里可能有丢失的数据,我想跳过插入table_1不匹配外键table_2的行。

使用PostgreSQL 10.16,由Visual C build 1800编译,64位

共有2个答案

杜俊爽
2023-03-14

我使用了这个答案中查询的变体。感谢@_horse_with_no_name

这是对我有用的查询:

with data_table(col1, col2, col3, col4,
                col5, col6) as (
    values
        ('value1','','1','num1','1900-01-01'::date, '9999-12-31'::date),
        ('value2','','1','num2','1900-01-01'::date, '9999-12-31'::date)   
)
insert into table_1(col1, col2, col3,
                    col4, col5, col6)
select d.col1, d.col2, d.col3, d.col4,
       d.col5, d.col6
from data_table d
where exists (select 1
              from table_2 t2
              where t2.col1 = d.col4)
on conflict(col1, col2, col3, col4, col5, col6) do nothing;
令狐嘉运
2023-03-14

没有违反约束的“什么都不做”选项。您可以在表_2中创建一个虚拟字段,以便在父表中无法匹配该值时,该值可以在表_2中引用(排序占位符值)。

或者,您可以使用映射表来删除外键约束。这样,您可以决定映射表是否应该插入新记录。这不太可能是满足您设计目标的最佳方式。

table_1
    id
    ...  other data fields ...

table_2
    id
    ...  other data fields ...

map_table
    id
    table1_id (FK)
    table2_id (FK)
 类似资料:
  • 主要内容:执行 master 分支变更,出现冲突,解决冲突假设要在分支中执行更改,修改分支中的代码。添加一个计算长度的函数:,代码变化如下 - 假设验证代码后,没有问题就提交这些更改。 执行 master 分支变更 同时在分支中,另外一个开发人员()还会更改了内容,并将其更改推送到分支。 验证差异后,现在就提交更新内容。 在分支上,我们已经实现了一个函数。假设经过测试后,提交并将其更改推送到分支。 出现冲突 假设另外一个开发人员()想看看我们在分支上做了

  • 我试图在csv文件中读取列艺术家,专辑,歌曲和标签。 我希望像这样填充artist_album_song表: 我已经设计并正在尝试填充以下表。问题是填充artist_album_song表中的外键,就像我在csv中读到的那样。 插入到这个表中的最佳方法是什么,它可以实现我在下面使用的INSERT语句中尝试做的事情(返回语法错误)?谢谢。 在尝试了下面链接中各种不同的语句后,我仍然无法让它发挥作用。

  • 对于很多人来说,合并时出现冲突是非常可怕的事,这就好像一不小心格式化了自己的硬盘一样。在这一章节里我将为你消除这种恐惧。 你不会把事情搞砸 首先你应该记住,你总是可以撤销一个合并操作,并且返回到冲突发生之前的状态。也就是说,你永远有机会放弃并重新开始。 如果你已经掌握了一些关于其它的版本控制系统的使用经验,例如 Subversion ,你可能会很难过。因为在 Subversion 中处理冲突是被大

  • 我正在使用libGdx,创建一个简单的平台游戏。我正在使用Tiled创建映射和LibGdx tiledMap呈现器。它的设置与SuperKoalio libgdx示例类似。 我现在的碰撞检测,它只是确定玩家是撞到了它的右边,上面还是下面的一个瓷砖。当它检测到右侧碰撞时,它将玩家状态设置为Standing。对播放机的控制是通过InputHandler完成的。当D键被按下时,它将玩家的状态设置为行走,

  • 我有一个使用Spring Boot/hibernate的简单项目,在单元测试中插入新值时有bug。对于测试,我使用了一个带有虚拟数据(data.sql)的新数据库,在启动后,当插入测试运行时,我出现了一个错误“密钥冲突”: 我管理带有注释的ID:@ID@GeneratedValue(策略=GenerationType.Auto) @data@entity@table公共类地址{

  • 问题内容: 我有两个实体: 我正在尝试通过执行以下操作插入文件(以及随后的标签): 然后,我使用以下命令将文件插入DAO: 在我的日志中,我在“文件”表中看到一个插入,在标签表中看到2个插入,但是,指向我的文件表(file_id)的标签表中的外键为NULL。 我可能做错了什么? 问题答案: 您不是将标签的文件设置为文件,而是将标签的文件设置为文件。请记住,在OOP中,与关系模型相反,您必须设置关系