我们知道 char 是定长类型的数据,如果数据长度小于定义的长度,会在字符串尾部加上空格。而对于空格的处理,对于等式匹配,或length等,会忽略空格。而对于like 或模式匹配,空格不能忽略。
一、对于系统自动补全的空格
1、数据类型为varchar
对于varchar 类型,由于字符串尾部没有补全空格,like 与 等式比较结果没有区别。
testdb=# create table tab1(id varchar(9)); CREATE TABLE testdb=# insert into tab1 values('123'); INSERT 0 1 testdb=# select * from tab1 where id='123'; id ----- 123 (1 row) testdb=# select * from tab1 where id like '123'; id ----- 123 (1 row)
2、数据类型为char
对于char类型,字符串后会补全空格字符。对于等式匹配,这种空白字符会忽略;对于模式匹配(like 或正则匹配),则会考虑空白字符。
testdb=# create table tab2(id char(9)); CREATE TABLE testdb=# insert into tab2 values('123'); INSERT 0 1 testdb=# select * from tab2 where id='123'; id ----------- 123 (1 row) testdb=# select * from tab2 where id like '123'; id ---- (0 rows)
二、对于数据自身带的空格
这里的空格是指字符串自身带的最后的空格。
1、数据类型为Varchar
对于varchar 类型的空格,在比较时,会比较空格。
testdb=# create table tab3(id varchar(9)); CREATE TABLE testdb=# insert into tab3 values('123 '); INSERT 0 1 testdb=# select * from tab3 where id='123'; id ---- (0 rows) testdb=# select * from tab3 where id like '123'; id ---- (0 rows)
2、数据类型为char
插入的空格与系统自动补全的空格是一样的。
testdb=# create table tab4(id char(9)); CREATE TABLE testdb=# insert into tab4 values('123 '); INSERT 0 1 testdb=# select * from tab4 where id='123'; id ----------- 123 (1 row) testdb=# select * from tab4 where id like '123'; id ---- (0 rows) testdb=# select length(id) from tab4; length -------- 3 (1 row)
三、对于varchar 与char 类型的空格
对于varchar 与 char,最后的空格是不一样的。
testdb=# select length(substr(id,4,1)) from tab3; length -------- 1 (1 row) testdb=# select length(substr(id,4,1)) from tab4; length -------- (1 row)
再看个例子:
--KingbaseES test=# select length(substr('1 3 '::char,2,1)),length(substr('1 3 '::char,4,1)) from dual; length | length --------+-------- | (1 row) test=# select length(substr('1 3 '::varchar,2,1)),length(substr('1 3 '::varchar,4,1)) from dual; length | length --------+-------- 1 | 1 (1 row) --Postgresql testdb=# select length(substr('1 3 '::char,2,1)),length(substr('1 3 '::char,4,1)) ; length | length --------+-------- 0 | 0 (1 row) testdb=# select length(substr('1 3 '::varchar,2,1)),length(substr('1 3 '::varchar,4,1)) ; length | length --------+-------- 1 | 1 (1 row)
四、oracle 的 char 与 varchar
可以看到,二者是没有区别的。
SQL> create table tab1(id1 char(9),id2 varchar(9)); Table created. SQL> insert into tab1 values('1 3 ','1 3 '); 1 row created. SQL> select length(substr(id1,2,1)),length(substr(id1,5,1)),length(substr(id2,2,1)) from tab1; LENGTH(SUBSTR(ID1,2,1)) LENGTH(SUBSTR(ID1,5,1)) LENGTH(SUBSTR(ID2,2,1)) ----------------------- ----------------------- ----------------------- 1 1 1