sql - Mutating table error when trying to Insert into Table with select
问题描述
I have a problem having mutating table error when inserting data from select in PLSQL.
When im doing insert like this:
insert into pozycje_dokumentow
(
pozycja_dokumentu,
id_dok,
stawka_vat,
miejsce_skladowania,
jm_kod_jednostka_miary,
ilosc_jm_sprzedazy,
ilosc,
indeks_czesci
)
values(
1014,
1882706,
23,
4709,
'L15',
388.33,
386.713,
26539
);
It all works good, but when i try to do it in this way:
insert into pozycje_dokumentow
(
pozycja_dokumentu,
id_dok,
stawka_vat,
miejsce_skladowania,
jm_kod_jednostka_miary,
ilosc_jm_sprzedazy,
ilosc,
indeks_czesci
)
Select
1014,
1882706,
23,
4709,
'L15',
388.33,
386.713,
26539
from dual
I get an error in before_insert trigger on table pozycje_dokumentow: ORA-20298: ORA-04091: ORA-04091: table name is mutating, trigger/function may not see it
What is the diffrence in those two querys?
Trigger's body that is generating error, only when doing insert select from dual:
select nvl(max(lp),0) + 1
into :new.lp
from pozycje_dokumentow
where id_dok = :new.id_dok
group by id_dok;
解决方案
I wouldn't say that it is insert
that makes the difference. If you run the first insert
(which "works OK") twice, you'd - I believe - get the same error.
It is probably because trigger code selects from the pozycje_dokumentow
, the same table that is affected by insert
so it is mutating.
I guess you'll have to rewrite the trigger (or change the way you're doing the whole thing).
A sequence approach which will, hopefully, fix your problems.
create sequence seqa;
create or replace trigger trg_bi_podok
before insert on pozycje_dokumentow
for each row
begin
:new.id := seqa.nextval;
end;
As of "unique PK per document": there is a way to do that. Here's a sample code you might use (i.e. adjust to your situation) - it requires an autonomous transaction function which locks the table that contains PK values, fetches the next PK number and releases the table.
CREATE TABLE EVIDENCIJA_BROJ
(
DP NUMBER(4) NOT NULL,
REDNI_BR NUMBER NOT NULL,
WHAT VARCHAR2(10 BYTE),
GODINA NUMBER(4)
);
FUNCTION f_get_evidencija_broj (par_dp IN NUMBER,
par_what IN VARCHAR2 DEFAULT 'EVID',
par_godina IN NUMBER DEFAULT NULL)
RETURN NUMBER
IS
PRAGMA AUTONOMOUS_TRANSACTION;
l_redni_br evidencija_broj.redni_br%TYPE;
BEGIN
SELECT b.redni_br + 1
INTO l_redni_br
FROM evidencija_broj b
WHERE b.dp = par_dp
AND ( b.godina = par_godina
OR par_godina IS NULL)
AND b.what = par_what
FOR UPDATE OF b.redni_br;
UPDATE evidencija_broj b
SET b.redni_br = l_redni_br
WHERE b.dp = par_dp
AND b.what = par_what
AND ( b.godina = par_godina
OR par_godina IS NULL);
COMMIT;
RETURN (l_redni_br);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
LOCK TABLE evidencija_broj IN EXCLUSIVE MODE;
INSERT INTO evidencija_broj (dp,
godina,
what,
redni_br)
VALUES (par_dp,
par_godina,
par_what,
1);
COMMIT;
RETURN (1);
END f_get_evidencija_broj;
推荐阅读
- python - 在列表中查找不共享元素(没有任何重叠)的 3 元素集组
- css - React Native - 如何重叠边距?
- javascript - 使多个 javascript 函数在同一个 HTML 页面上工作
- python - openpyxl - 我无法将单元格样式复制到另一个中
- algorithm - O(n) 的快速排序的最佳情况是什么?
- python - 如何从文件读取中的唯一匹配项中正确清除列表-> 文件写入
- java - 如果 newFixedThreadPool 没有返回值则报错
- reactjs - Mui-datatables 自定义搜索
- node.js - 如何将日期作为输入传递给节点中的 SQL Server 查询
- docker - 无法使用在 Docker 上运行的 Kafka 和 Zookeeper 创建 Kafka 主题