关于引用外键时的矛盾(新加讨论:关于唯一性约束的问题)——怎么连来灌水的都没有? (100分)

  • 主题发起人 主题发起人 guqs
  • 开始时间 开始时间
G

guqs

Unregistered / Unconfirmed
GUEST, unregistred user!
在SQL Server 中:
我有一个表T1,其中一个字段a1可以为空,同时它是另一个表T2的外键,T1.a1<-T2.iID。
当a1付值时,取的是T2.iID,同时由于应用上的要求,需要有时清除掉A1的值,使其仍然为
空,但由于外键的限制,无法更改字段A1=NULL。
请教各位:如何解决这个问题?最好能仍然保持外键约束。
 
难道没人回答吗?
 
你的数据库搞对没有啊,外键也能为空?
 
不是吧,外键如果为空的话,那你定义外键有什么意思啊。哈哈
好好,查查帮助吧,看看外键的功能啊。
 
在T2 中加一个 代替null 的行

旧T1 -> 新T1
A1 ... A1 ...
NULL 1
2 2
3 3
NULL 1
2 2

旧T2 -> 新t2
iID XX iID XX
2 A 2 A
3 B 3 B
1 <NULL>
 
to honghs,lovefox:
“外键也能为空 ”、“外键如果为空的话,那你定义外键有什么意思啊”
使用外键,同时有时要求为空,当然应用中可能遇到这样的情况:
比如,我有一个设备表和一个用户表,当为用户装上设备时,必须是设备表里的设备,当然
用户也可以不装设备,此值为空。这种情况你们难道没有想到过吗?

to madm:
你的方法我想过,但感觉不好。因为固定一个字段表示为空的情况,那么必须初始时就输入,
同时不能删除这个记录,哪怕没有引用。

to ALL:
总算有人来看一下了。
这个问题我现在已经解决了。我发现当设置外键时,不选择“创建时检查现存数据”项,
就可以设置字段为空,同时若设置非空值而主键表中没有的话,外键约束会起作用而报错。

但我同时有另外一个问题:
当用户选择了一种设备时,其他用户不能再选择这个设备,也就是同时要求USER_SheBeiID
为唯一,但是当建立了唯一性约束后,即使选择“忽略空值”选项,也只能有一条为空,其它
记录设为空时就出错了。有什么好办法没有?难到只能不设唯一性约束,在程序中检查或用存
储过程检查?
大家来出出主意。

 
我的方法比较保险

“另外一个问题”用我的方法不会有问题

 
to madm:
我的另一个问题好象更不能用你的方法,
我要求的是若有值时值必须唯一,同时允许有多个空值,怎么能用你的方法解决?
你用一条记录放空值,还不是只能引用一次?
 
你的数据库设计有问题

要照你说的,一个设备只能被选一次,应该建设备使用表
1 设备id为主键
2 使用该设备的用户

那象你说的那么夸张
 
to chenlh:
你的意思是不是说在用户表和设备表外另建一个设备使用表,每当用户安装设备时,就往表
中增加一个记录,去除设备时,就删除表里相应记录。
这倒是一个好办法。
当时为了省事,而且为了减少连接表的数目,就直接把使用设备的ID放到用户表里了,看来
应该分出来。
另外,问一下,如果不是要求唯一性,是不是就可以把它合到用户表里呢?
 
数据库设计的方面就不多说了,
我只说你想要的完全可以在触发器实现。
 
guqs, 可以是可以,但当一个用户选多台设备的话就不太合适了

建议用户表只有userid一个主键
 
T1
A1 A2
1 甲
2 乙
3 丙
1 丁
2 戊

t2
iID XX
2 A
3 B
1 <NULL>

select t2.XX , t1.a2 from t1 inner join t2 on t1.a1=t2.iID

t2.XX t1.a2
<NULL> 甲
A 乙
B 丙
<NULL> 丁
A 戊

是不是要这个?!
 
感谢大家的帮助,
我觉得可以采用两种方法,
一种可以采用chenlh说的另外建一个设备使用表,使关系独立出来更加明确,也方便限定
外键和唯一性。
另一种是用原来的表但不建立外键和唯一性约束,但是在存储过程或触发器中写相应语句
做约束,这种方法使用起来比较灵活,改变约束规则,比如决定改为可以两个用户用同一
设备,改起来很方便,不用动表结构。
madm的方法不太好,原因我说过了。

给几位发分了。
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
598
import
I
I
回复
0
查看
655
import
I
后退
顶部