PostgreSQL重复键值在冲突时使用时违反唯一约束插入时不执行任何操作
表def:PostgreSQL重复键值在冲突时使用时违反唯一约束插入时不执行任何操作,sql,postgresql,sql-insert,plpgsql,Sql,Postgresql,Sql Insert,Plpgsql,表def: 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,
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,但它没有问题
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;
如果不指定目标,它是否有效
insert into lazy_product_stock (product_id, warehouse_id)
select _product_id, warehouse.id
from warehouse
where siteid = site_id
on conflict do nothing;
什么都不做
是唯一一个不需要指定目标的冲突操作,这使得此解决方案在这里成为可能。似乎我有两个这样的函数在导致问题的相同逻辑上触发。谢谢大家的帮助。使用插入重复键值时出现相同错误,违反了唯一约束“lazy\u product\u stock\u comb\u idx2”编辑您的问题并显示表的定义。我怀疑您还有其他唯一的约束。更新了问题以包含表定义无关,但是:循环完全没有必要,只会使事情变得非常缓慢。我无法重现:不,它失败,出现相同的约束错误错误:重复键值违反唯一约束“lazy\u product\u stock\u comb\u idx2”