不允许空不会插入默认值?

hanshuai888 2010-06-21 03:25:05
数据库SQL Server 2005,有个表所有字段都不允许为空,但都设置了默认值。新增记录时只给个别字段赋值,没有赋值的字段会提示不允许NULL插入,为什么不会自动插入默认值呢?要怎么做才可以让字段为空时插入默认值?
...全文
496 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
hanshuai888 2010-06-21
  • 打赏
  • 举报
回复
我从网上找到答案了,原来确实不是数据库的问题,是Linq to SQL的问题,原文如下:

Linq to SQL中,对于数据库中允许为null,但是设置了默认值的字段,默认生成的Model会将null值插入,不会使用数据库的默认值。



下面有几个和默认值相关的Attribute:

1.ColumnAttribute中的 IsDbGenerated 属性 :如果设置了IsDbGenerated为True,则此属性只使用数据库中设置的默认值。一般只有默认值为getdate()的时间戳字段使用此属性。因为数据库默认值的作用是在没有值的时候使用,而不是始终使用数据库默认值。

2.ColumnAttribute中的DbType属性

3.ColumnAttribute中的CanBeNull属性



举例:

[Column(Storage="_nvarcharNotnull", DbType="NVarChar(50) NOT NULL", CanBeNull=false, IsDbGenerated=true)]





在数据库中的字段上设置了Not Null, 自动生成的代码上如下:

来源:(http://blog.sina.com.cn/s/blog_443469830100e1u2.html) - LINQ to SQL的默认值问题_KIRA基拉_新浪博客
[Column(Storage="_nvarcharNotnull", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]

但是new一个实例的时候此字段仍然是null,并且在Insert的时候尝试插入null值并发生错误:

不能将值 NULL 插入列 'nvarcharNotnull',表 'DEMO.dbo.Table1';列不允许有空值。INSERT 失败。

这是一个自动生成代码的Bug。

既然不能使用数据库的默认值,尝试设置字段的默认值。设置DefaultValueAttribute:

[Column(Storage="_nvarcharNotnull", DbType="NVarChar(50) NOT NULL", CanBeNull=false), DefaultValue("B")]

发现此属性无效,字段默认值仍然为null,又是一个Bug!

唯一的办法是用初始化器设置私有字段的默认值:private string _nvarcharNotnull = "AAA";



总结:

实验证明没有办法使用数据库的默认值,只有一种字段能使用数据库设置的默认值---不能传入数值的时间戳列。通过设置IsDbGenerated 属性可以实现。

目前的解决办法是在私有字段上手工同步设置数据库的默认值。如果想保证数据库字段不因为代码疏忽而插入null值,设置字段默认值是无用的,仍然会被LINQ插入默认值,只能够设置此字段为not null。
IvyAngta 2010-06-21
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 kerafan 的回复:]
SQL code
insert into tb(a,b,c) values('a','b',default)
[/Quote]

这个正解!
hanshuai888 2010-06-21
  • 打赏
  • 举报
回复
楼上的大哥,我也在数据库上运行了下,确实没错。但是用Linq却总是不行
表si_user所有字段允许为空,所有字段设置默认值,后台代码如下:
ForumDataContext datacontext = new ForumDataContext();
si_user tb = new si_user();
tb.username = TextBox1.Text.Trim();
tb.password = FormsAuthentication.HashPasswordForStoringInConfigFile(TextBox2.Text.Trim(), "MD5");
datacontext.si_user.InsertOnSubmit(tb);
datacontext.SubmitChanges();
插入新记录后,除了username和password外其余字段均为NULL而不是默认值
ask_chang 2010-06-21
  • 打赏
  • 举报
回复
引用 4 楼 xys_777 的回复:
就让其允许空,默认值方可插入


我把它设置成允许空了,虽然不提示错误了,但是值是NULL,不是默认值。不会和我用Linq有关吧?

你写一个Insert into语句看看。
上面那样是可以的。
TheGodOfGods 2010-06-21
  • 打赏
  • 举报
回复
其它一些情况:

if object_id('tb') IS NOT NULL
drop table tb
create table tb(id int, name varchar(20) NOT NULL default (''))
insert into tb(id)
select 2
select * from tb
/*
id name
----------- --------------------
2
(1 行受影响)
*/

--非空 + default空值(矛盾?)
if object_id('tb') IS NOT NULL
drop table tb
create table tb(id int, name varchar(20) NOT NULL default (NULL))
insert into tb(id)
select 2
/*
消息 515,级别 16,状态 2,第 3 行
不能将值 NULL 插入列 'name',表 'ymw_test.dbo.tb';列不允许有空值。INSERT 失败。
*/

if object_id('tb') IS NOT NULL
drop table tb
create table tb(id int, name varchar(20) default (NULL))
insert into tb(id)
select 2
select * from tb
/*
id name
----------- --------------------
2 NULL
(1 行受影响)
*/

TheGodOfGods 2010-06-21
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 hanshuai888 的回复:]

引用 4 楼 xys_777 的回复:
就让其允许空,默认值方可插入

我把它设置成允许空了,虽然不提示错误了,但是值是NULL,不是默认值。不会和我用Linq有关吧?
[/Quote]

这种情况怎么出来的?
我在SQLServer05上运行结果

if object_id('tb') IS NOT NULL
drop table tb
create table tb(id int, name varchar(20) default ('YYY'))
insert into tb(id)
select 2
select * from tb
/*
id name
----------- --------------------
2 YYY
(1 行受影响)
*/
claro 2010-06-21
  • 打赏
  • 举报
回复
一时间语塞!
hanshuai888 2010-06-21
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 xys_777 的回复:]
就让其允许空,默认值方可插入
[/Quote]
我把它设置成允许空了,虽然不提示错误了,但是值是NULL,不是默认值。不会和我用Linq有关吧?
hanshuai888 2010-06-21
  • 打赏
  • 举报
回复
默认值为''不会和NULL一样吧?我的两个单引号中间没空格。另外我发现数值类型字段设置了不允许为空和默认值后,不赋值时会自动变成默认值,其他类型的不行。
hanshuai888 2010-06-21
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 orchidcat 的回复:]
引用 4 楼 xys_777 的回复:

就让其允许空,默认值方可插入


up
[/Quote]
我也想让它允许为空,可是数据库设计要求所有字段都不允许为空啊,有没有别的办法
Mr_Nice 2010-06-21
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 xys_777 的回复:]

就让其允许空,默认值方可插入
[/Quote]

up
hanshuai888 2010-06-21
  • 打赏
  • 举报
回复
我用的是Linq,插入的时候只给非空的字段赋值,其他字段就没写,想让它插入默认值,可是不行。
永生天地 2010-06-21
  • 打赏
  • 举报
回复
就让其允许空,默认值方可插入
老黎 2010-06-21
  • 打赏
  • 举报
回复
insert into tb(a,b,c) values('a','b',default)
xyj052 2010-06-21
  • 打赏
  • 举报
回复
是不是你的插入语句有问题
你插入的时候,不插入那个字段,应该会显示出默认值的啊
是不是你插入了NULL啊
pkdebug 2010-06-21
  • 打赏
  • 举报
回复
这个问题没有见过,设置了默认值,不起作用?帮你顶一下!

34,593

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧