避免在 oracle 中挂起会话
avoid hung sessions in oracle
我在 pl/sql 中有一个程序,它适用于少量数据。问题是,当数据量很大时,cursor6有时会挂session,其他用户无法访问table5。
table5 有一个主键列 "ocf",它是用户 ID,所以每个用户只能访问对应于他的用户 ID 的行。即使在这些情况下,cursor6 锁定 table5 并创建一个死会话,我不明白如何,但它不允许其他用户访问它
即使他们使用 table5 中的其他行。是否有解决方案来重新创建该游标以进行更新或使用可能做同样事情的东西,从而避免挂起会话?
cursor cursor6(pf varchar2,PO number, psu varchar2) is select * from table5 where ocf=PO and .. for update;
row1 cursor6%rowtype;
BEGIN
delete table5 where ocf=PO;
commit;
open cursor1;
fetch cursor1 into wv,wd;
if cursor1%found then
open cursor2;
fetch cursor2 into wf;
if cursor2%found then
while cursor2%found loop
open cursor3;
fetch cursor3 into wco;
if cursor3%found then
while cursor3%found loop
open cursor5;
fetch cursor5 into ws;
while cursor5%found loop
open cursor4;
fetch cursor4 into ..;
if cursor4%found then
open cursor6(..);
fetch cursor6 into row1;
if cursor6%notfound then insert into table5 values (..);
else update table5 set ... where current of cursor6;
end if;
close cursor6;
end if;
close cursor4;
end loop;
close cursor5;
end loop;
end if;
close cursor3;
end loop;
end if;
close cursor2;
end if;
close cursor1;
commit;
delete table5 where ocf=PO;
commit;
天哪,6 个嵌套循环祝你好运。
cursor6 locks the table5 and create a dead session and, I don't understand how, but it doesn't allow other users to acces
当外键列未被索引时会发生这种情况。我建议您检查是否是这种情况,如果是,则创建索引。
这里有一个查询(作者是 Tom Kyte)(我没有 link 原件,抱歉;Google 如果你想要的)显示未索引的外键约束。我通过添加 what 来稍微修改一下以显示:
PAR_WHAT
:
0
- 只显示缺失的
1
- 显示有效的
NULL
- 显示全部
我建议你先 运行 它与 PAR_WHAT = 0
。
WITH forkey
AS (SELECT DECODE (b.table_name, NULL, '****', 'ok') Status,
a.table_name,
a.columns column_1,
b.columns column_2
FROM ( SELECT SUBSTR (a.table_name, 1, 30) table_name,
SUBSTR (a.constraint_name, 1, 30) constraint_name,
MAX (
DECODE (position,
1, SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
2, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
3, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
4, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
5, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
6, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
7, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
8, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
9, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
10, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
11, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
12, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
13, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
14, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
15, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
16, ', ' || SUBSTR (column_name, 1, 30),
NULL))
columns
FROM user_cons_columns a, user_constraints b
WHERE a.constraint_name = b.constraint_name
AND b.constraint_type = 'R'
GROUP BY SUBSTR (a.table_name, 1, 30),
SUBSTR (a.constraint_name, 1, 30)) a,
( SELECT SUBSTR (table_name, 1, 30) table_name,
SUBSTR (index_name, 1, 30) index_name,
MAX (
DECODE (column_position,
1, SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
2, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
3, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
4, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
5, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
6, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
7, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
8, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
9, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
10, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
11, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
12, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
13, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
14, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
15, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
16, ', ' || SUBSTR (column_name, 1, 30),
NULL))
columns
FROM user_ind_columns
GROUP BY SUBSTR (table_name, 1, 30),
SUBSTR (index_name, 1, 30)) b
WHERE a.table_name = b.table_name(+)
AND b.columns(+) LIKE a.columns || '%'
AND a.table_name NOT LIKE 'HEP_DP%')
SELECT f.status,
f.table_name,
f.column_1,
f.column_2
FROM forkey f
WHERE f.status =
CASE
WHEN :par_what = 1 THEN 'ok'
WHEN :par_what = 0 THEN '****'
ELSE f.status
END
ORDER BY f.table_name, f.column_1, f.column_2;
我在 pl/sql 中有一个程序,它适用于少量数据。问题是,当数据量很大时,cursor6有时会挂session,其他用户无法访问table5。 table5 有一个主键列 "ocf",它是用户 ID,所以每个用户只能访问对应于他的用户 ID 的行。即使在这些情况下,cursor6 锁定 table5 并创建一个死会话,我不明白如何,但它不允许其他用户访问它 即使他们使用 table5 中的其他行。是否有解决方案来重新创建该游标以进行更新或使用可能做同样事情的东西,从而避免挂起会话?
cursor cursor6(pf varchar2,PO number, psu varchar2) is select * from table5 where ocf=PO and .. for update;
row1 cursor6%rowtype;
BEGIN
delete table5 where ocf=PO;
commit;
open cursor1;
fetch cursor1 into wv,wd;
if cursor1%found then
open cursor2;
fetch cursor2 into wf;
if cursor2%found then
while cursor2%found loop
open cursor3;
fetch cursor3 into wco;
if cursor3%found then
while cursor3%found loop
open cursor5;
fetch cursor5 into ws;
while cursor5%found loop
open cursor4;
fetch cursor4 into ..;
if cursor4%found then
open cursor6(..);
fetch cursor6 into row1;
if cursor6%notfound then insert into table5 values (..);
else update table5 set ... where current of cursor6;
end if;
close cursor6;
end if;
close cursor4;
end loop;
close cursor5;
end loop;
end if;
close cursor3;
end loop;
end if;
close cursor2;
end if;
close cursor1;
commit;
delete table5 where ocf=PO;
commit;
天哪,6 个嵌套循环祝你好运。
cursor6 locks the table5 and create a dead session and, I don't understand how, but it doesn't allow other users to acces
当外键列未被索引时会发生这种情况。我建议您检查是否是这种情况,如果是,则创建索引。
这里有一个查询(作者是 Tom Kyte)(我没有 link 原件,抱歉;Google 如果你想要的)显示未索引的外键约束。我通过添加 what 来稍微修改一下以显示:
PAR_WHAT
:0
- 只显示缺失的1
- 显示有效的NULL
- 显示全部
我建议你先 运行 它与 PAR_WHAT = 0
。
WITH forkey
AS (SELECT DECODE (b.table_name, NULL, '****', 'ok') Status,
a.table_name,
a.columns column_1,
b.columns column_2
FROM ( SELECT SUBSTR (a.table_name, 1, 30) table_name,
SUBSTR (a.constraint_name, 1, 30) constraint_name,
MAX (
DECODE (position,
1, SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
2, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
3, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
4, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
5, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
6, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
7, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
8, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
9, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
10, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
11, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
12, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
13, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
14, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
15, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
16, ', ' || SUBSTR (column_name, 1, 30),
NULL))
columns
FROM user_cons_columns a, user_constraints b
WHERE a.constraint_name = b.constraint_name
AND b.constraint_type = 'R'
GROUP BY SUBSTR (a.table_name, 1, 30),
SUBSTR (a.constraint_name, 1, 30)) a,
( SELECT SUBSTR (table_name, 1, 30) table_name,
SUBSTR (index_name, 1, 30) index_name,
MAX (
DECODE (column_position,
1, SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
2, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
3, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
4, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
5, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
6, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
7, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
8, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
9, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
10, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
11, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
12, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
13, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
14, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
15, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
16, ', ' || SUBSTR (column_name, 1, 30),
NULL))
columns
FROM user_ind_columns
GROUP BY SUBSTR (table_name, 1, 30),
SUBSTR (index_name, 1, 30)) b
WHERE a.table_name = b.table_name(+)
AND b.columns(+) LIKE a.columns || '%'
AND a.table_name NOT LIKE 'HEP_DP%')
SELECT f.status,
f.table_name,
f.column_1,
f.column_2
FROM forkey f
WHERE f.status =
CASE
WHEN :par_what = 1 THEN 'ok'
WHEN :par_what = 0 THEN '****'
ELSE f.status
END
ORDER BY f.table_name, f.column_1, f.column_2;