sql - PostgreSQL 重复键值违反唯一约束,同时使用冲突时不执行插入操作

标签 sql postgresql sql-update sql-insert plpgsql

表格定义:

CREATE SEQUENCE IF NOT EXISTS lazy_product_stock_id_seq;
CREATE TABLE "public"."lazy_product_stock" (
    "id" int4 NOT NULL DEFAULT nextval('lazy_product_stock_id_seq'::regclass),
    "product_id" int4,
    "hold" int4 DEFAULT 0,
    "quantity" int4 DEFAULT 0,
    "warehouse_id" int4,
    PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX lazy_product_stock_pkey ON public.lazy_product_stock USING btree (id)
CREATE INDEX lazy_product_stock_product_id_idx ON public.lazy_product_stock USING btree (product_id)
CREATE INDEX lazy_product_stock_warehouse_id_idx ON public.lazy_product_stock USING btree (warehouse_id)
CREATE UNIQUE INDEX CONCURRENTLY "lazy_product_stock_comb_idx2" ON "public"."lazy_product_stock" USING BTREE ("product_id","warehouse_id");

我有一个将新行插入数据库的函数:

CREATE OR REPLACE FUNCTION sp_lazystock_i_f(_product_id int4, site_id int4) RETURNS VOID AS $$
declare
warehouse record;
BEGIN
FOR warehouse IN select id from warehouse where siteid = site_id LOOP
    insert into lazy_product_stock (product_id, warehouse_id) VALUES (_product_id, warehouse.id) ON CONFLICT (product_id,warehouse_id) DO NOTHING;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;

失败了

duplicate key value violates unique constraint "lazy_product_stock_comb_idx2"

索引

CREATE UNIQUE INDEX CONCURRENTLY "lazy_product_stock_comb_idx2" ON "public"."lazy_product_stock" USING BTREE ("product_id","warehouse_id");

尽管使用重复值自行运行相关插入,但没有问题。

insert into lazy_product_stock (product_id, warehouse_id) VALUES (123, 1234) ON CONFLICT (product_id,warehouse_id) DO NOTHING;

Query 1 OK: INSERT 0 0, 0 rows affected

我不明白函数和单个语句之间的区别是什么?

这也没有问题:

do $$
declare
warehouse record;
begin
    FOR warehouse IN select id from warehouse where siteid = 123 LOOP
    insert into lazy_product_stock (product_id, warehouse_id) VALUES (12345, warehouse.id) ON CONFLICT (product_id,warehouse_id) DO NOTHING;
END LOOP;
end; $$ LANGUAGE plpgsql;

同样的错误

insert into lazy_product_stock (product_id, warehouse_id)
    select _product_id, warehouse.id
    from warehouse where siteid = site_id
    on conflict (product_id, warehouse_id) do nothing;

我使用的是 Postgresql 12.3

最佳答案

为什么要使用循环呢?怎么样:

insert into lazy_product_stock (product_id, warehouse_id)
    select _product_id, w.id
    from warehouse where siteid = site_id
    on conflict (product_id, warehouse_id) do nothing;

关于sql - PostgreSQL 重复键值违反唯一约束,同时使用冲突时不执行插入操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64245161/

相关文章:

mysql - SQL - 选择超过 1 天的条目。错误 #1305 函数不存在

sql - 使用 1 个查询插入多行

swift - Vapor,使用 PostgreSQL 流畅地保存/创建复杂模型

postgresql - 需要解释 PostgreSQL 中的字符类型

安卓sql更新

c# - 为什么更新外键后引用约束不一致?

mysql - 在 MySQL 中使用左连接时尝试更新表会出现语法错误

sql - 在 MS-SQL 中更改表时, View 中的列会移位

mysql - SQL - 聚合函数 - COUNT 函数的误用

sql - 使用一组整数作为 SQL 键的最佳方法?