今天因為功能需求對以前編寫的oracle存儲過程做了一個修改:
CREATE OR REPLACE PROCEDURE drivingrankings
(
par_BASE_OIL_WARE in number,
par_PARAMETER_ONE in number,
par_PARAMETER_TOW in number,
par_BASE_WARM_UP in number,
par_PARAMETER_THREE in number,
par_EACH_SPEED_UP_OIL_WARE in number)
AS
avg_mileage number;
abc_rec b_energy_driving_data%rowtype;
avg_consumption number;
avg_acceleration_num number;
avg_acceleration number;
paraA number(16,2);
paraB number(16,2);
paraC number(16,2);
result number(16,2);
cursor abc_cur is select tbox_sn,avg(total_mileage),avg(total_consumption),avg(acceleration_num),owner,model_code
from B_ENERGY_DRIVING_DATA group by owner,TBOX_SN,model_code order by owner,tbox_sn,model_code;
BEGIN
avg_mileage := 0.0;
avg_consumption :=0.0;
avg_acceleration :=0.0;
paraA :=0.0;
paraB :=0.0;
paraC :=0.0;
result :=0.0;
open abc_cur;
Loop
Fetch abc_cur into abc_rec.tbox_sn,avg_mileage,avg_consumption,avg_acceleration_num,abc_rec.owner,abc_rec.model_code;
Exit when abc_cur%notfound;
paraA:=((0.01 * par_BASE_OIL_WARE * avg_mileage / avg_consumption) - par_PARAMETER_ONE) / par_PARAMETER_ONE;
paraB:=(par_PARAMETER_TOW - (avg_consumption - par_BASE_WARM_UP) / 60) / par_PARAMETER_TOW;
paraC:=(par_PARAMETER_THREE - (100 * avg_acceleration * par_EACH_SPEED_UP_OIL_WARE / avg_consumption)) / par_PARAMETER_THREE;
result:=(paraA + paraB + paraC) * 100 / 3;
if(result >= 100 ) then
begin
result:= 99;
end;
end if;
if(result <1) then
begin
result:= 1;
end;
end if;
update b_energy_driving_rankings set environmental_score = result WHERE cruuent_user = abc_rec.owner;
end loop;
Exception
when others then
close abc_cur;
Dbms_Output.put_line(Sqlerrm);
if abc_cur%isopen then
close abc_cur;
end if;
END;
需要將update替換為insert into 操作, 在做insert into操作時需要先對表數據進行刪除。在SQL中刪除表數據可以用delete 和 TRUNCATE;二者的區別在於
delet刪除數據不會釋放內存空間,truncate刪除數據會釋放內存空間。
SQL 刪除語法為: delete table_name, truncate table tab1;
結果我傻傻的在存儲過程當中也這樣寫:
BEGIN
avg_mileage := 0.0;
avg_consumption :=0.0;
avg_acceleration :=0.0;
paraA :=0.0;
paraB :=0.0;
paraC :=0.0;
result :=0.0;
truncate table tab1;
如此寫法編譯的時候並不會報錯,但查看存儲過程狀態為Ivalid(我是小菜,原諒我);網上例子一看才知道需要先定義變量,然后執行CREATE OR REPLACE PROCEDURE drivingrankings()
AS
drop_tab1 varchar2(2048);
BEGIN
drop_tab1 := 'TRUNCATE TABLE b_energy_driving_rankings';
execute immediate drop_tab1;
end;
(看來存儲過程還是和直接sql不一樣)
第二個問題就是標題問題,資源正忙或資源無效
這個問題是在將update操作修改為insert 操作之后出現的。出現問題時存儲過程:
open abc_cur;
Loop
Fetch abc_cur into abc_rec.tbox_sn,avg_mileage,avg_consumption,avg_acceleration_num,abc_rec.owner,abc_rec.model_code;
Exit when abc_cur%notfound;
paraA:=((0.01 * par_BASE_OIL_WARE * avg_mileage / avg_consumption) - par_PARAMETER_ONE) / par_PARAMETER_ONE;
paraB:=(par_PARAMETER_TOW - (avg_consumption - par_BASE_WARM_UP) / 60) / par_PARAMETER_TOW;
paraC:=(par_PARAMETER_THREE - (100 * avg_acceleration * par_EACH_SPEED_UP_OIL_WARE / avg_consumption)) / par_PARAMETER_THREE;
result:=(paraA + paraB + paraC) * 100 / 3;
if(result >= 100 ) then
begin
result:= 99;
end;
end if;
if(result <1) then
begin
result:= 1;
end;
end if;
insert into b_energy_driving_rankings(CRUUENT_USER,MODEL_CODE,ENVIRONMENTAL_SCORE,TBOX_SN)
values(abc_rec.owner,abc_rec.model_code,result,abc_rec.tbox_sn);
end loop;
測試的時候反復調用幾次存儲過程,就會提示資源正忙,有時候調用一次在調用就會提示資源正忙。查看消息游標無法close。很疑惑,以前update的時候是沒問題
應該還是在做insert 操作時出問題了,還是麻煩了度娘一下,才發現遠了在insert之后沒有 commit;
修改代碼如下:
insert into b_energy_driving_rankings(CRUUENT_USER,MODEL_CODE,ENVIRONMENTAL_SCORE,TBOX_SN)
values(abc_rec.owner,abc_rec.model_code,result,abc_rec.tbox_sn);
commit;
就沒有在報資源正忙錯誤。有點疑惑 沒有commit為何數據可以保存到數據庫,為什么沒commit就會出現該錯誤!