应用场景:
某公司购买了一套javaWEB版的ERP系统,已经使用几年了(数据量很大)。随着公司的发展,有些资料已经不再使用(比如部门)了,但是用户在使用的时候只能在应用中将废弃的部门标注上失效标记,或者失效日期,不能从数据库中删除这些记录。而当其他用户在新建或者修改数据的时候,可能会用到部门表的信息。这时问题就出现,因为当初设计的时候没有考虑到显示的时候过滤掉这些失效部门的信息,所以用户还是能够选择这些失效的部门(it‘s not science!)。
怎么解决呢?两种方法:
第一:在应用系统中加上过滤条件,过滤掉失效的部门。
第二:删除数据库中的资料。
如果按照第一种方法,就必须修改java文件,重新编译,重启服务器,对于一个大型的ERP系统来说这需要比较长的一段时间,而且这段时间之内,客户不能做任何的操作。
如果按照第二种方法来做,那就简单了。delete from 部门表 where 失效=Y or 失效日期 IS NOT NULL,很简单,对吧?但是作为一个部门信息表少不了一大堆的外键,而且有的部门虽然废弃了,但是与该部门相关的某些信息可能仍在使用(客户说:这些就先不删吧!你们先把没用到的删掉),这时怎么办?一条一条的删?我试了下,删一条记录用2分多钟,最后还删除失败了
。所以就想了下面的这个方法:
DECLARE
CURSOR cur_del IS SELECT dp FROM 部门表 WHERE co = 'X' AND cancdat IS NOT NULL ORDER BY dp DESC;
rec_del cur_del%ROWTYPE;
BEGIN
OPEN cur_del;
LOOP
FETCH cur_del INTO rec_del;
EXIT WHEN cur_del%NOTFOUND;
BEGIN
EXECUTE IMMEDIATE 'delete from 部门表 where co =''X''and cancdat is not null and dp = '''||rec_del.dp||'''';
Dbms_Output.put_line('delete row success where dp =; '||rec_del.dp);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
CONTINUE;
END;
END LOOP;
END;
/
这个是Oracle11g的用法,11g之前好像不支持continue,可以将上面红色的部门改成下面的形式或者使用其它方式:
for i in 1..1 loop
BEGIN
EXECUTE IMMEDIATE 'delete from 部门表 where co =''X''and cancdat is not null and dp = '''||rec_del.dp||'''';
Dbms_Output.put_line('delete row success where dp =; '||rec_del.dp);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
exit;
END;
end loop;
这个方法我也是在网上看到的,但是写这篇文章的时候却发现找不到了。。。。