delphi2009在SQL2000上出现的问题(其他版本我没有尝试):1.建表table1,table2如下:
create table table1(
id int identity primary key,
name varchar(10) default '' not null
);
create table table2(
id int identity primary key,
name nvarchar(10) default '' not null
);2.测试一:
运行
insert into table1 (name) values('');
insert into table2 (name) values('');
都能通过.3.测试二:
建一vcl应用程序,窗体上添加如下控件:
ADOConnection1 用来连接数据库
ADODataset1,Datasource1,DBGrid1 用来操作Table1(name字段是varchar类型)
ADODataset2,Datasource2,DBGrid2 用来操作Table2(name字段是nvarchar类型)
DBGrid1和DBGrid2各新增一条记录(只需要输入name列,然后按上下箭头键即可提交)
然后尝试将DBGrid1和DBGrid2中的name列编辑,清除输入的内容(应该就是0长度字符串了把)
提交时,问题出来了:
DBGrid1能提交,DBGrid2提交不了,提示如同标题:非空列不能更新为NULL.
说明:
insert into table1 (name) values('');
insert into table2 (name) values('');
两条SQL可以通过刚刚的ADOConnection来Execute成功.
请大家探讨指点.谢谢!

解决方案 »

  1.   

    对,sql语法里插入空值用NULL吧,''你那是插入空字符
      

  2.   

    非空列不能更新为null  讲的不是很清楚的吗?列数据不允许为空
      

  3.   

    非空列不能更新为NULL,列数据不能为空,delete约束
      

  4.   

    主要问题应该是出在id上,也就是索引,因为你在更新的时候,把id也设置为空,而id是主键,不能为空,所以提示错误.
      

  5.   

    insert into table1 (name) values(''); 
    insert into table2 (name) values(''); 
    应该可以插入到非空列啊,原因很简单的,自己再找找吧。
      

  6.   

    insert into table1 (name) values(''); 
    insert into table2 (name) values(''); 
    应该可以插入到非空列啊,原因很简单的,自己再找找吧。
      

  7.   

    说明Table1在(或BDE)在提交的时候, 把''转为NULL了.
      

  8.   

    在你的SQL语句里面 对空值进行转换 
      

  9.   

    isnull(id,0) AS ID  ---- 把 NULL 的值 变为 0 
      

  10.   

    对于数据敏感控件,空字符串被认为是Null
      

  11.   

    和数据库也有关系的,在oracle中对于null有说明,它不等于''
      

  12.   

    此空非空,此null非null,很清楚的东西呀!!'' <> null
      

  13.   

    多谢大家的提议,但是这个列在系统设计中因为是同其他列一起作为主键,所以不能删除约束。
    楼上的有几位老兄可能没有弄清楚问题,呵呵,kaikai_kk说得比较清楚,我是要赋值一个0长度的字符串,而非NULL,这样的用法在字段为varchar时能正常工作,但是换成nvarchar时就不行了,希望不是delphi对nvarchar处理的bug。
    自己顶一下
    欢迎大家接着讨论指导。非常感谢各位热心的指导。
      

  14.   

    咳咳,你赶快结贴吧~这个问题没啥好讨论的。我要说大道理了~~ 
    varchar(10) 这个类型,当你朝里面插入不足10个长度的字符的时候,会自动在后面补空格直到10个;
    nvarchar(10)这个类型,当你朝里面插入不足10个长度的字符时,他是不会补的。
    你觉得你朝varchar(10)里面插了个0长度的字符成功了,其实你插进去的是10个空格。
    你觉得你朝nvarchar(10)里面插了0长度的字符不成功,其实不是DELPHI的BUG~因为他不自动补空格,当然就是NULL,而你的建表语句又不允许他为NULL,当然就不行了
      

  15.   

    Parameters[0].Value:=Unassigned;
    Unassigned传进去就是null
      

  16.   

    你用MSSQL2000的事件探查器跟踪一下DELPHI提交这两条指令有什么不同之处。或者,是不是在提交时DELPHI自动进行了转换。
      

  17.   


    yf老兄的观点我有异议:
    1、我在delphi中,用adoconnection的Execute方法执行
    insert into table1 (name) values(''); 
    insert into table2 (name) values(''); 
    这两条语句时都能成功,从而推翻了你的“Delphi自动补足空格”之说。
    你或者会说SQL会自动补足空格,这点也是不对的,你可以SQL对Char类型的会自动补足空格,因为Char是定长类型,而对于Varchar类型,则不会自动补足尾部的空格,这也正是Char和Varchar的区别之一。而Varchar和Nvarchar类型都是可变长的类型,不会自动补充尾部的空格
      

  18.   

    这个错误是delphi扔出来的。
    varchar类型的提交零长度的可以,事件查看器可以看到执行的SQL,nvarchar的根本就没有执行SQL,delphi自己就事先扔出了一个例外!应该是个思路上的Bug.
      

  19.   

    空值用Unassigned表示
    Unassigned是Variant类型的。而Variant类型在pascal里可以表示任意类型。
    例子:Query.SQL.Text:='insert into 表1 (列1) values (:a) ';
    Query.Parameters[0].Valus:=Unassigned;
    Query.ExecSQL;
      

  20.   

    感谢大家指导。
    结贴了,因为不是单独一位大侠的方法直接解决的,所以大家参与者有分!不能删除约束!
    我只好采用比较笨拙的办法:对这样的列手动赋值为' ',是一个空格,而不是0个空格。
    对非空nvarchar型的字段(不是varchar)0个空格在delphi7和之前的平台都能通过,delphi2009通不过,至于delphi8和之后的其他版本没有做过测试!
    所以大家不要讨论varchar型的,这种类型的是没有问题的。只有非空的nvarchar型的,在delphi2009出现了这种变态的问题。
    希望这个帖子中,各位高手的高见对我们大家日后碰到这样的问题能提供一些参考!
      

  21.   

    可能是我在前面的提议讲述不是很清楚。其实这个问题应该是delphi2009的TADODataset或者父类组件的一个Bug,因为对非空的字段,用TADOConnection实例直接执行插入语句:
    insert into table1 (name) values(''); 
    Insert是没有问题的,
    但是如果用TADODataset来对字段赋值: 
    ADODataset2.FieldByName('name').AsString = '';
    则通不过,就爆出了标题上的提示。
    针对本案,假如name是varchar型的字段,就没有问题,如:
    ADODataset1.FieldByName('name').AsString = '';
    就可以通过本案中,ADODataset1和ADODataset2的区别就是
    ADODataset1对应的table1表,name是非空的varchar
    ADODataset2对应的table1表,name是非空的nvarchar这个问题只是变通的解决了,并非是完美解决。
    源于对技术的执着,如果哪位大侠有高见,还可以继续跟帖。如果真正的解决了,我会另开一个送分的帖子感谢!
    我的QQ:963967218