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成功.
请大家探讨指点.谢谢!
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成功.
请大家探讨指点.谢谢!
解决方案 »
- 为什么Create里的代码不执行?关于TIdTCPClient的
- 求助!!查询后的数据集怎么保存在SQLServer数据库中,在怎样读取出来?(解决后马上给分!)
- 如何采用DDN专线,从计算机上发送和接收短信息到车辆监控终端上
- sql问题:这几句能用一句话实现么?
- delphi6的TNMUDP控件有问题吗?
- 为什么动态创建的窗体经USES语句引用后,在并未创建该窗体时仍然会消耗资源?
- 菜问题请教,请进!
- 急求JBuilder6.0下载!
- 如何实现:用鼠标按住一个控件后,使整个窗体随着鼠标的移动而移动
- 我要怎么办??? 很菜的子窗体问题
- 用DCC32.exe编译出错
- QReport的title的band,手工添加内容,遇到一个问题
insert into table2 (name) values('');
应该可以插入到非空列啊,原因很简单的,自己再找找吧。
insert into table2 (name) values('');
应该可以插入到非空列啊,原因很简单的,自己再找找吧。
楼上的有几位老兄可能没有弄清楚问题,呵呵,kaikai_kk说得比较清楚,我是要赋值一个0长度的字符串,而非NULL,这样的用法在字段为varchar时能正常工作,但是换成nvarchar时就不行了,希望不是delphi对nvarchar处理的bug。
自己顶一下
欢迎大家接着讨论指导。非常感谢各位热心的指导。
varchar(10) 这个类型,当你朝里面插入不足10个长度的字符的时候,会自动在后面补空格直到10个;
nvarchar(10)这个类型,当你朝里面插入不足10个长度的字符时,他是不会补的。
你觉得你朝varchar(10)里面插了个0长度的字符成功了,其实你插进去的是10个空格。
你觉得你朝nvarchar(10)里面插了0长度的字符不成功,其实不是DELPHI的BUG~因为他不自动补空格,当然就是NULL,而你的建表语句又不允许他为NULL,当然就不行了
Unassigned传进去就是null
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类型都是可变长的类型,不会自动补充尾部的空格
varchar类型的提交零长度的可以,事件查看器可以看到执行的SQL,nvarchar的根本就没有执行SQL,delphi自己就事先扔出了一个例外!应该是个思路上的Bug.
Unassigned是Variant类型的。而Variant类型在pascal里可以表示任意类型。
例子:Query.SQL.Text:='insert into 表1 (列1) values (:a) ';
Query.Parameters[0].Valus:=Unassigned;
Query.ExecSQL;
结贴了,因为不是单独一位大侠的方法直接解决的,所以大家参与者有分!不能删除约束!
我只好采用比较笨拙的办法:对这样的列手动赋值为' ',是一个空格,而不是0个空格。
对非空nvarchar型的字段(不是varchar)0个空格在delphi7和之前的平台都能通过,delphi2009通不过,至于delphi8和之后的其他版本没有做过测试!
所以大家不要讨论varchar型的,这种类型的是没有问题的。只有非空的nvarchar型的,在delphi2009出现了这种变态的问题。
希望这个帖子中,各位高手的高见对我们大家日后碰到这样的问题能提供一些参考!
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