ora-04091 表正在变异-
Posted
技术标签:
【中文标题】ora-04091 表正在变异-【英文标题】:ora-04091 table is Mutating- 【发布时间】:2013-10-03 04:18:03 【问题描述】:我正在使用一个函数来比较表 1 和表 2 中的所有列并返回“Y”或“N”。基于此,我将更新我的表 1。
但是当我运行合并语句时,它会显示一个错误:
ora-04091 - Table1 正在变异,触发器/函数可能看不到它
我该如何解决这个问题?
CREATE OR REPLACE function DataChange (in_epmname varchar2) return char is
v_epmname table2.empname%type;
v_DATA_COUNT varchar2(2);
v_DATA_CHANGED char;
begin
SELECT COUNT (*) into v_DATA_COUNT
FROM
(
SELECT trim(column1||column2||column3)
FROM table1
WHERE empname = in_epmname
UNION
SELECT trim(column1||column2||column3)
FROM table2
WHERE empname = in_epmname
);
If (v_DATA_COUNT = '1' ) Then
v_DATA_CHANGED :='N';
else
v_DATA_CHANGED :='Y';
end if;
return v_DATA_CHANGED;
end DataChange ;
我使用的合并语句是:
CREATE OR REPLACE PROCEDURE updatetabble1 AS
BEGIN
MERGE
INTO Table1 DBC
USING ( SELECT
empname,
DataChange(empname) as DATA_CHANGED
FROM employee
) TBL_MAIN
ON ( DBC.empname = TBL_MAIN.empname )
WHEN MATCHED THEN
UPDATE SET
DBC.DATA_CHANGED = TBL_MAIN.DATA_CHANGED;
COMMIT;
END updatetabble1;
【问题讨论】:
不确定我是否完全理解您想要实现的目标,但是在更新表 2 时使用触发器以在表 1 中设置该标志不是更好吗? Mutating Table in Oracle 11 caused by a function 的可能重复项 Table1 是一个 kill and fill 表,它有 50 多列来自其他表。在 Table1 中的这个 DATA_CHANGED 列上,如果发现为“Y”,那么我将使用我在 Table1 的 50 多列中收到的最新记录更新我的 Table2 感谢 Cade,还有其他方法可以使用相同的函数来实现吗? 【参考方案1】:Chade 我试过这个选项它没有给我任何错误。
CREATE OR REPLACE PROCEDURE updatetabble1 AS
BEGIN
MERGE
INTO Table1 DBC
USING ( Select ename from
(
Select ename
from
(
Select ename, column1||Column2||Column3 from table1
union
Select ename, column1||Column2||Column3 from table2
)
)
GROUP BY ename HAVING count(*) > 1
) TBL_MAIN
ON ( DBC.empname = TBL_MAIN.empname)
WHEN MATCHED THEN
UPDATE SET DBC.DATA_CHANGED = 'Y';
COMMIT;
END updatetabble1;
【讨论】:
奇怪的是它的工作原理..你不是缺少一个 GROUP BY 子句吗?应该是这样的:Select ename from ( Select ename, column1||Column2||Column3 from table1 union Select ename, column1||Column2||Column3 from table2 ) GROUP BY ename HAVING count(*) > 1
(如果你不需要where diff > 1
没错,乍得。它是一个拼写错误。我已经纠正了。也将 where 替换为有条件。【参考方案2】:
您可以考虑使用临时表,即 I.E.:
create global temporary table table12_gt(empname varchar2(30), is_changed char(1));
CREATE OR REPLACE PROCEDURE updatetabble1_2 AS
BEGIN
insert into table12_gt
select empname,
CASE
WHEN count(v) > 1 THEN
'Y'
ELSE
'N'
END is_changed
from (SELECT empname, trim(column1 || column2 || column3) v
FROM table1
UNION
SELECT empname, trim(column1 || column2 || column3) v FROM table2)
GROUP BY empname;
MERGE INTO Table1 DBC
USING (SELECT empname, is_changed as DATA_CHANGED FROM table12_gt) TBL_MAIN
ON (DBC.empname = TBL_MAIN.empname)
WHEN MATCHED THEN
UPDATE SET DBC.DATA_CHANGED = TBL_MAIN.DATA_CHANGED;
COMMIT;
END updatetabble1_2;
这相当“快速而肮脏”,但可以作为一个开始
【讨论】:
以上是关于ora-04091 表正在变异-的主要内容,如果未能解决你的问题,请参考以下文章
ORA-04091: 表 JOSEP.EMP 正在变异,触发器/函数可能看不到它
ORA-04091: 表 [blah] 正在变异,触发器/函数可能看不到它
如何修复 ORA-04091:表正在变异,触发器/函数可能看不到它?
ORA-04091:表正在变异,触发器/函数可能看不到它,ORA-06512:,ORA-06512:在“SYS.DBMS_SQL”,第 1721 行