star_yao 发表于 2008-07-08 10:37

主键列值为空

有一张表,对3个字段建了复合主键,但是为什么有个字段还会存在空值:em14: , 怎么样会导致这样的情况...请教..:em02:

liaosnet 发表于 2008-07-08 15:33

原帖由 star_yao 于 2008-7-8 10:37 发表 http://bbs.chinaunix.net/images/common/back.gif
有一张表,对3个字段建了复合主键,但是为什么有个字段还会存在空值:em14: , 怎么样会导致这样的情况...请教..:em02:

请确定是""这样的空字符串还是null......

liaosnet 发表于 2008-07-08 15:34

create table "informix".t1
(
    a char(10),
    b char(10),
    c char(10),
    d char(10),
    primary key (a,b,c)
)extent size 16 next size 16 lock mode page;

Database selected.

> insert into t1 values("a","b","","d");

1 row(s) inserted.

> select * from t1;


a          b          c          d         

a          b                     d         

1 row(s) retrieved.

> update t1 set b=null where a="a";

703: Primary key on table (t1) has a field with a null key value.
Error in line 1
Near character position 31
> update t1 set d=null where a="a";

1 row(s) updated.

> select * from t1;


a          b          c          d         

a          b                              

1 row(s) retrieved.

hero--008 发表于 2008-07-08 15:35

不应该!注意null<>''

star_yao 发表于 2008-07-09 11:47

回复 #2 liaosnet 的帖子

是""空字符串,呵呵...那为什么unload出来,load的时候报错:Primary key on table table_name has a field with a null key value.?

xxyyy 发表于 2008-07-09 11:53

这是unload程序本身的bug
unload的时候空串应该是|\|,空值是||。
但是你的unload的时候空串也弄成||了,所以load的时候解释成空值了,所以出错。


在低版本的informix有这个bug,高版本已经修正了,解决办法是,避免更新数据的时候写空字符串,一定要有个字符,比如'0'字符。
这样,数据库就不会弄混了。

[ 本帖最后由 xxyyy 于 2008-7-9 11:55 编辑 ]

star_yao 发表于 2008-07-09 12:39

回复 #6 xxyyy 的帖子

非常感谢...
我如果把导出的信息内容(|| 改成|\|),呵呵,先去试下...

ivhb 发表于 2008-07-09 21:39

原帖由 xxyyy 于 2008-7-9 11:53 发表 http://bbs.chinaunix.net/images/common/back.gif
这是unload程序本身的bug
unload的时候空串应该是|\|,空值是||。
但是你的unload的时候空串也弄成||了,所以load的时候解释成空值了,所以出错。


在低版本的informix有这个bug,高版本已经修正了,解决 ...


你这个说法是有问题的。
“空串”这个定义你误解了。
如果一个字段里面包含了null,unload肯定是||(连续的竖线),而绝对不会如你所说|\|,这个格式是什么?
这个格式说明该字段至少包含了一个字符,该字符是"|"(分隔符本身)。
至于2楼的测试
insert into x-table values ('a', 'b', '', 'c');
在informix里面,这是个障眼法。informix的client工具,对于literal的空串,自动的解释成至少一个空白字符的串。
informix的逻辑是,程序员知道自己想干什么。如果想插入空值,程序员一定会用null,如果已经写成了'',表明程序员
不想插入空值!
实际上,你可以用如下进行测试:
insert into x-table values ('my-key', 'b', '', 'd');
select * from x-table where c = '      ';
select * from x-table where c = '';
select * from x-table where c = '                                                                     ';
看到了么? 实际上,你写的c=后面的字串,不管多长都可以,只要你愿意,也不管多短,都是一样的。想想看? 到底是为什么?

实际上,你要是用esql/c来书写。比如
c_col = 0x00;// 当然你也可以写 strcpy (c_col, "");都是一样的
insert into x-table values ('my-key', 'b', :c_col, 'd');

这时候,如果c字段是主键的一部分,该insert语句会报错。应该是违反了非空约束。

我说明白了么?

ivhb 发表于 2008-07-09 22:03

“在informix里面,这是个障眼法。informix的client工具,对于literal的空串,自动的解释成至少一个空白字符的串。
informix的逻辑是,程序员知道自己想干什么。如果想插入空值,程序员一定会用null,如果已经写成了'',表明程序员
不想插入空值!”
应该更正一下,在char定义的字段里面,存储一个不是null,又不包含任何字符,是做不到的。在varchar里面应该可以做到。
我手头没有informix,没有测试过。

xxyyy 发表于 2008-07-10 10:22

原帖由 ivhb 于 2008-7-9 22:03 发表 http://bbs.chinaunix.net/images/common/back.gif
“在informix里面,这是个障眼法。informix的client工具,对于literal的空串,自动的解释成至少一个空白字符的串。
informix的逻辑是,程序员知道自己想干什么。如果想插入空值,程序员一定会用null,如果已经 ...

informix的逻辑是对的,但是他忘记了,操纵数据库,除了程序员之外,还有维护员,数据库需要备份、恢复、导入、导出等操作的,在这个过程中如果不严格区分空值和空串,会导致很多错误。

char型的列是不能保存空字符串的,这个我明白。

我的实际意思是说,informix的dbexport和unload工具是有bug的,我们要想办法绕过这个bug。
页: [1]
查看完整版本: 主键列值为空