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

外键能不能为null?
看到书上有这样一句话:外键的值不允许参照相应主表中不存在的主键值,或者外键为空值.

但我下面的一个练习,却可以使外键为空,对此感到很疑惑

--创建用户表
create   table   Users
(
  userID   int   identity(1,1)   primary   key,
  username   varchar(20)   not   null,
  password   varchar(20),
)

--创建帐套表
create   table   Account
(
  accountID   int   identity(1,1)   primary   key,
  name   varchar(20),
  type   bit,
 
)

--创建用户帐套表
create   table   UserAccount
(
  userID   int   ,  
  accountID     int  
)

--对表useraccount添加外键
alter   table   useraccount
add
constraint   FK_useraccount_users   foreign   key(userID)   references   Users(userID),
constraint   FK_useraccount_account   foreign   key(accountid)   references   Account(accountID)

--对users表插入数据
    insert   into   Users   select   '王五 ', '123 '
    union   select   '张三 ', '123 '
    union   select   '李四 ',null

--对Account表插入数据        
    insert   into   Account  
    select   '个人帐 ',1
    union   all
    select   '家庭帐 ',1
    union   all  
    select   '公司帐 ',0

--对userAccount表插入数据
insert   into   userAccount
  select   1,2
union   select   1,2
union   select   2,3
union   select   null,null  

--显示useraccount表数据
select   *   from   useraccount

查询结果中有记录显示插入了null值,我个人认为既然外键是引用了主表中主键的值,而主表中主键的值是不可能为null的,所以从表中的外键值也不能为null,否者会破坏数据的完整性规则.
有谁能更清楚的解释一下这个概念?



------解决方案--------------------
外键可以为空的,一个表的关键的标识是主键,外键是否为空不影响表的结构及数据库设计概念的.外键只起个关联表的作用.
至于书上提到的外键不能为空是对的,但实践中在数据库里没有创建关联时,好像是外键,实则不是外键.不知LZ是不是没有创建数据库关联
------解决方案--------------------
可以为NULL

create table t1(id int primary key ,col char(1))
create table t2(id int foreign key references t1(id),col char(1))
insert into t1 values(1, 'a ')
insert into t1 values(2, 'a ')
insert into t1 values(3, 'a ')
insert into t2 values(null, 'd ')
insert into t2 values(1, 'd ')
insert into t2 values(1, '3 ')
select * from t2
drop table t2,t1

------解决方案--------------------
联机丛书中准确的解释是

如果在 FOREIGN KEY 约束的列中输入非 NULL 值,则此值必须在被引用的列中存在,否则将返回违反外键约束的错误信息。

也就是说外键中可以有null,除非外键列定义了not null
------解决方案--------------------
呵呵,除了在TIANTIAN 问,也在这里啊

http://blog.sina.com.cn/dotnba