Y yysun Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-09 #1 一个表是主表,另一个从表与它有一对多关系。 需要主表中关键字段改变,从表相应的字段也改变, 主表中记录删除,从表相应的记录也删除, 如何实现比较好呢?
D dwwang Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-09 #2 最简单的办法是DBMS支持级联(Cascade)更新和删除, 具体设置及调用方式可参见你所用的DBMS说明. 如果不能支持,当然只能程序维护了. 删除比较方便,先删子表相应记录,再删主表的记录; 修改麻烦一点, 1. 先对主表插入一条伪(dummy)记录, 2. 将子表中要修改的记录的外码值改为主表的伪记录的相应码值. 3. 而后再修改主表记录, 4. 将子表中要修改的记录的外码值改为需要的外码值 5. 将主表伪记录删除掉 实际上,支持级联更新的DBMS也是这个过程,只是在内部进行而已.
最简单的办法是DBMS支持级联(Cascade)更新和删除, 具体设置及调用方式可参见你所用的DBMS说明. 如果不能支持,当然只能程序维护了. 删除比较方便,先删子表相应记录,再删主表的记录; 修改麻烦一点, 1. 先对主表插入一条伪(dummy)记录, 2. 将子表中要修改的记录的外码值改为主表的伪记录的相应码值. 3. 而后再修改主表记录, 4. 将子表中要修改的记录的外码值改为需要的外码值 5. 将主表伪记录删除掉 实际上,支持级联更新的DBMS也是这个过程,只是在内部进行而已.
Y yysun Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-09 #3 谢谢dwwang, 今天您也能闯进来,真行啊! 如果我是两个TTable对付dbase的数据表(*.dbf)有好办法吗?
D dwwang Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-09 #4 那就只有用我说的第二种办法了,自己的程序来维护。(见上面) 但是现在Internet上数据库控件这么多,是否可以先 搜索一下,有没有能实现此功能的。只要是有源码的, 用起来可以比较放心(当然同时也可以看到它是怎么做的)。
那就只有用我说的第二种办法了,自己的程序来维护。(见上面) 但是现在Internet上数据库控件这么多,是否可以先 搜索一下,有没有能实现此功能的。只要是有源码的, 用起来可以比较放心(当然同时也可以看到它是怎么做的)。
D dwwang Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-09 #6 我所说的插入伪记录,是指对于支持Reference Key的DBMS而言。 我回答这个问题时还不知道你使用DBASE,后来也忘记加以说明。 对于支持Reference Key的DBMS,如果不插入伪记录,显然不可 能实现记录码值的修改。因为无论先改主表还是子表都将导致外码冲突。 对于DBASE之类的表(如果不支持外码概念),则通过程序可随 意增删改,只要确保程序逻辑无误就可以了。 咦?转了一圈,我等于什么也没说呀!呜呜呜...(作委屈状)
我所说的插入伪记录,是指对于支持Reference Key的DBMS而言。 我回答这个问题时还不知道你使用DBASE,后来也忘记加以说明。 对于支持Reference Key的DBMS,如果不插入伪记录,显然不可 能实现记录码值的修改。因为无论先改主表还是子表都将导致外码冲突。 对于DBASE之类的表(如果不支持外码概念),则通过程序可随 意增删改,只要确保程序逻辑无误就可以了。 咦?转了一圈,我等于什么也没说呀!呜呜呜...(作委屈状)
S Sunset Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-09 #7 伪记录是数据库自身的解决办法,自己的程序里不用伪记录。 修改主记录前记下主记录的关键字,主记录修改后检查关键字是否改变,如果关键 字改变就到子表中修改外码值等于主记录原关键字的记录,使其外码值与主记录现 关键字相符。 我现在做的系统大多是这种一对多的主从结构,我都是这样解决的。这种情况比较 常见,如果数据库本身不支持,全靠程序来解决会比较烦琐。我忙完这段后会考虑 写个控件解决这一问题。
伪记录是数据库自身的解决办法,自己的程序里不用伪记录。 修改主记录前记下主记录的关键字,主记录修改后检查关键字是否改变,如果关键 字改变就到子表中修改外码值等于主记录原关键字的记录,使其外码值与主记录现 关键字相符。 我现在做的系统大多是这种一对多的主从结构,我都是这样解决的。这种情况比较 常见,如果数据库本身不支持,全靠程序来解决会比较烦琐。我忙完这段后会考虑 写个控件解决这一问题。
Y yysun Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-10 #8 谢谢dwwang和Sunset, 对于不支持关键字的dbase,靠程序解决一对多关系时,再加主关键字唯一性的控制 就更麻烦了.
D dwwang Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-10 #9 SunSet说的不对呀! 如果你真的在DBMS中定义了外码,你在修改主记录的时候, 如果修改了码值,系统就会出错,因为子表中的记录没有 码值可以参考了,怎么可能允许你修改呢? 例如: 主表中的码值: xxx 子表中的外码值: xxx 如果你想把主表中的码值改为yyy,则子表中的xxx的记录就没有了参照, 系统会拒绝你修改主表中的码值. 反过来,你记住了主表码值xxx,当你知道用户要把它改成yyy时,你想先去 子表中将相应记录改为yyy.但这时候主表中还没有码值yyy的记录,同样违反了 外码规则,系统仍会拒绝. 我们通常戏称为"死锁". 这一点是绝对不可能有别的办法实现的. (试想一下,DBMS自身可利用的资源与方法比编程者多得多,如果不通过 插入伪记录就能实现,DBMS怎么还会用这种方法呢?)
SunSet说的不对呀! 如果你真的在DBMS中定义了外码,你在修改主记录的时候, 如果修改了码值,系统就会出错,因为子表中的记录没有 码值可以参考了,怎么可能允许你修改呢? 例如: 主表中的码值: xxx 子表中的外码值: xxx 如果你想把主表中的码值改为yyy,则子表中的xxx的记录就没有了参照, 系统会拒绝你修改主表中的码值. 反过来,你记住了主表码值xxx,当你知道用户要把它改成yyy时,你想先去 子表中将相应记录改为yyy.但这时候主表中还没有码值yyy的记录,同样违反了 外码规则,系统仍会拒绝. 我们通常戏称为"死锁". 这一点是绝对不可能有别的办法实现的. (试想一下,DBMS自身可利用的资源与方法比编程者多得多,如果不通过 插入伪记录就能实现,DBMS怎么还会用这种方法呢?)
C CJ Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-10 #10 在用DBASE建立关键字可以用写文件(文本文件或数据库)的方法: 每次加入记录则在以前的数字上+1,当然文件开始应该有个0。 我记得有一个控件实现了这个功能可惜没有SOURCE。
S Sunset Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-11 #11 不知道dwwang兄用什么数据库,小弟现在就用Paradox,反正是没问题。
D dwwang Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-11 #12 那我就不清楚了,Paradox是不是真支持外码。 “真正的”DBMS都是不行的(SQLServer/SYBASE/ORACLE/...) 不过老兄要编一个支持这种功能的控件,我真得先替老孙谢谢你了 这可是功德无量的事儿啊!
那我就不清楚了,Paradox是不是真支持外码。 “真正的”DBMS都是不行的(SQLServer/SYBASE/ORACLE/...) 不过老兄要编一个支持这种功能的控件,我真得先替老孙谢谢你了 这可是功德无量的事儿啊!
Y yysun Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-11 #13 是啊,肯定会有不少人对Sunset即将出台的这个控件感兴趣的.
Y yysun Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-14 #14 Sunset的答案尚未等到,其他大虾有维护dbase数据库一对多关系的办法吗?
D dwwang Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-14 #15 说实话,我觉得编这样一个控件费力不讨好, 什么控件呢? query?table? 用dbedit时如何处理,直接写sql时又怎么处理? 即使支持外码的DBMS,我们有时用try..except去实现, 有时也需要自己编程维护,这要看对界面的要求 和个人的习惯. 因此我觉得用sql语句,插入子表前到主表里去 lookup一下,不是很麻烦.
说实话,我觉得编这样一个控件费力不讨好, 什么控件呢? query?table? 用dbedit时如何处理,直接写sql时又怎么处理? 即使支持外码的DBMS,我们有时用try..except去实现, 有时也需要自己编程维护,这要看对界面的要求 和个人的习惯. 因此我觉得用sql语句,插入子表前到主表里去 lookup一下,不是很麻烦.
Y yysun Unregistered / Unconfirmed GUEST, unregistred user! 1998-10-15 #16 举个例子来说, 用Database Form Expert 生成的 Form上有两个TTable(对付dbase的), 具有一对多关系,主Table做删除和修改主关键字时,对子Table是不负责任的, 在子Table留下了一大堆“无头尸体” :-( 我可以用个TQuery删除这些“无头尸体”,但是得在程序的某个地方启动一下,例如 onFormClose. 想像中如果有个控件,例如TTableBridge,可以设置主Table和子Table List, 根据主Table关键字变化,自动引发子Table的操作 ... 再设想下去,我自己就写成这个控件了
举个例子来说, 用Database Form Expert 生成的 Form上有两个TTable(对付dbase的), 具有一对多关系,主Table做删除和修改主关键字时,对子Table是不负责任的, 在子Table留下了一大堆“无头尸体” :-( 我可以用个TQuery删除这些“无头尸体”,但是得在程序的某个地方启动一下,例如 onFormClose. 想像中如果有个控件,例如TTableBridge,可以设置主Table和子Table List, 根据主Table关键字变化,自动引发子Table的操作 ... 再设想下去,我自己就写成这个控件了
D dwwang Unregistered / Unconfirmed GUEST, unregistred user! 1998-11-06 #17 刚刚发现的信息,不知yysun是否看过: http://www.inprise.com/devsupport/bde/bdeapiex/dbidorestructure.html Examples 9,11 Paradox和DBase7是可以支持外码(主-子表关系)的, (这样至少解决了 '在子Table留下了一大堆“无头尸体” :-(') 其他的嘛,当然就用程序了,即使SQLServer也是这样的, 我说的那么多终于有用啦! 如果不用PDX或Dbase7,就又没办法了 :-(
刚刚发现的信息,不知yysun是否看过: http://www.inprise.com/devsupport/bde/bdeapiex/dbidorestructure.html Examples 9,11 Paradox和DBase7是可以支持外码(主-子表关系)的, (这样至少解决了 '在子Table留下了一大堆“无头尸体” :-(') 其他的嘛,当然就用程序了,即使SQLServer也是这样的, 我说的那么多终于有用啦! 如果不用PDX或Dbase7,就又没办法了 :-(
Y yysun Unregistered / Unconfirmed GUEST, unregistred user! 1998-11-06 #18 dwwang,真是非常感谢 . 待我细细看来 ...
D dwwang Unregistered / Unconfirmed GUEST, unregistred user! 1998-11-06 #19 不好意思,我昨天突然又发现(这哪叫什么发现啊!): Database Desktop中就是可以定义外码的,因此我提 供的网址不过是定以外码的功能的源程序而已. 因此关键问题还是用不用PDX或DBase7 :-(
不好意思,我昨天突然又发现(这哪叫什么发现啊!): Database Desktop中就是可以定义外码的,因此我提 供的网址不过是定以外码的功能的源程序而已. 因此关键问题还是用不用PDX或DBase7 :-(
Y yysun Unregistered / Unconfirmed GUEST, unregistred user! 1998-11-06 #20 我是使用 *.dbf, 虽然 BDE 的 Level = 7, 但是, 现有的 .dbf 在 Database Desktop 中显示为 dBase IV Table,所以就找不到定义外码的地方, paradox table 才有referential integrity 的定义。 我没有用过 dBase 7,还得研究一下: dBase 7 Table的dBase IV Table差异,如何转换,对现有系统是否有影响。 (但那是另外一个问题了,这个问题可以结束了。) 再次感谢 dwwang,您费心了。
我是使用 *.dbf, 虽然 BDE 的 Level = 7, 但是, 现有的 .dbf 在 Database Desktop 中显示为 dBase IV Table,所以就找不到定义外码的地方, paradox table 才有referential integrity 的定义。 我没有用过 dBase 7,还得研究一下: dBase 7 Table的dBase IV Table差异,如何转换,对现有系统是否有影响。 (但那是另外一个问题了,这个问题可以结束了。) 再次感谢 dwwang,您费心了。