日期:2014-05-18  浏览次数:20583 次

……紧急……(100分)高分求教数据库高手
这是一个oracle的问题,感觉,实现方法和SQL Server差不多,请各位高手帮忙啊。

现有一数据库(ORACLE 10G):Student
内有mst表 
  Mst_Student
Stu_Code(主健) Stu_Name ……
10001 A ……
10002 B ……
10003 C ……
…… …… ……
另有其他信息表若干
Inf_Student(没有主健)
Stu_Code(not null) Stu_Place ……
10001 F ……
10002 F ……
10003 F ……
…… …… ……
Le_Student(没有主健)
Stu_Code(not null) Stu_Lessin ……
10001 F ……
10002 F ……
10003 F ……
…… …… ……

即很多子表和主表一样都有 Stu_Code字段,且信息表的Stu_Code数据基于主表的数据。
即子表只添加主表中存在的Stu_Code。
此功能已通过程序在子表信息添加时实现。
子表的数据信息删除也没有问题。
但当我删除主表中的一条数据时,就要保证其他任何子表中都没有该数据。
  我的做法(删除Mst_Student表的Stu_Code为10001的数据):
首先利用数据字典查询出该数据库中所有有(Stu_Code)字段的表(主表除外),语句如下:
select table_name from ALL_TAB_COLUMNS where column_name='Stu_Code'
然后循环查询所有取出的数据表中该数据是否存在,如存在则取出表示。语句如下:
sql='select Stu_Code from ' + tb_Name[0] + 'where Stu_Code = 10001'
  +'Union'
  +'select Stu_Code from ' + tb_Name[1] + 'where Stu_Code = 10001'
  + ……
如果循环查询完毕且都没有该数据,则可以删除。
然后delete该数据,再commit
如果查询结果不为空,则在画面上表示该数据,提示不能删除信息。

  该做法的优点:简单
  缺点:①速度慢,因为是一个大型的系统,数据可能会有几万条。
     :②不安全(严重),由于在该数据被查询之后到被真正删除之前(commit),可能会有一段时间,在这段时间也存在着其他客户端添加子表Stu_Code为10001的可能性。所以造成查询结果变为假,而错删除了数据。
 
注:①因该数据库在设计时没有建立外健联接,所以不能用外健联接删除主健的方法(最头痛的地方),因数据量很大,所以最好也不要想着在程序中建立临时外健。
  ②每一个表都对应着相应的信息管理画面,不同的客户端不可打开相同的管理页面,且同一客户端也不可打开相同的管理页面。
  ③任何一个管理页面的操作都不影响其他页面的正常运行。

希望得到一条简单精炼的sql语句,可以返回存在的数据集,最重要的是删除数据时能够保证数据的完整性。游标实现也可以,但最好不要用存储过程。


------解决方案--------------------
我建议用第一种方法,一个一个删除,成功后commit,不成功rollback.

至于所谓的第二种办法是书上写的,实际没多大意义,不行,你实践一下就知道了.
------解决方案--------------------
我认为楼主的根本解决之道还是要建立外键关系.至于数据量大,楼主完全可以考虑采用维护窗口的方式.但楼主的问题我有一点还不清楚:当子表有数据存在时,您只是提示不能删除数据吗?还需要一个按钮用于强制删除数据的吗?
------解决方案--------------------
一、为什么不建立主外键关系?
二、你的子表不确定吗?如果确定,完全没有必要去搜索,
建议更新删除主表时用触发器保持主从表数据的完整性
------解决方案--------------------
在SQL里可用级联删除。。。
楼主可以delete类型触发器实现
删除主表的ID
create trigger del_tr on t1
instead of delete
as
..............................
------解决方案--------------------
触发器这种东西不能乱用,我还是建议建立主外健关系比较好点。
------解决方案--------------------
解决这种问题最好的方法就是利用外建,即安全有简单。
但如果非要用程序方法的话,那也只能一个一个的查询,然后再删除。
最好是在特定的时间段运行……