近日现场安装人员反映有一个存储过程一编译,服务器CPU使用率就居高不下,并且该存储过程也编译不过去,造成死锁。
经测试,创建类似存储过程,定位发生错误的语句,问题出现在一个select into 语句上,例子如下:
CREATE OR REPLACE PROCEDURE pro_test IS
n_sw110 NUMBER(4);
n_sw35 NUMBER(4);
n_sw10 NUMBER(4);
n_zr110 NUMBER(4);
n_zr35 NUMBER(4);
n_zr10 NUMBER(4);
n_zc110 NUMBER(4);
n_zc35 NUMBER(4);
n_zc10 NUMBER(4);
BEGIN
SELECT SUM(decode(t.names, '110KV上网电量', t.ids, NULL)),
SUM(decode(t.names, '35KV上网电量', t.ids, NULL)),
SUM(decode(t.names, '10KV上网电量', t.ids, NULL)),
SUM(decode(t.names, '110KV转入', t.ids, NULL)),
SUM(decode(t.names, '35KV转入', t.ids, NULL)),
SUM(decode(t.names, '10KV转入', t.ids, NULL)),
SUM(decode(t.names, '110KV转出', t.ids, NULL)),
SUM(decode(t.names, '35KV转出', t.ids, NULL)),
SUM(decode(t.names, '10KV转出', t.ids, NULL))
INTO n_sw110,
n_sw35,
n_sw10,
n_zr110,
n_zr35,
n_zr10,
n_zc110,
n_zc35,
n_zc10
FROM sys_cszd t
WHERE t.types = '关口类型'
AND (t.names = '110KV上网电量' OR t.names = '35KV上网电量' OR t.names = '10KV上网电量' OR t.names = '110KV转入' OR t.names = '35KV转入' OR t.names = '10KV转入' OR t.names = '110KV转出' OR
t.names = '35KV转出' OR t.names = '10KV转出');
END pro_test;
Oracle 版本:Release 9.2.0.1.0 字符集:SIMPLIFIED CHINESE_CHINA.ZHS16GBK
一个很奇怪的现象:
SUM(decode(t.names, '110KV上网电量', t.ids, NULL)) 如果换成SUM(decode(t.names, '110KV上网', t.ids, NULL)) 即把
decode语句中的'110KV上网电量'换成’'110KV上网'后,整个存储过程就能编译过去,否则会造成死锁,导致CPU使用率达50%以上!
百思不得其解。。。。。
而decode语句中的'10KV上网电量'就不会有问题!
无法解释
最后的解决办法:
把SUM(decode(t.names, '110KV上网电量', t.ids, NULL))
换成
SUM(decode(t.names, '110KV上网'||'电量', t.ids, NULL))
竟然就可以成功编译过去了,晕。
我不知道什么原因,有谁知道请告诉我,不胜感激!