Clo*_*eto 20 sql postgresql collation
为什么'2' 的初始空间大于'10'?
select ' 2' > '10';
?column?
----------
t
(1 row)
Run Code Online (Sandbox Code Playgroud)
我尝试了latin1和utf8英文整理:
List of databases
Name | Owner | Encoding | Collation | Ctype | Access privileges
-----------+------------+-----------+------------------+------------------+-----------------------
cpn | cpn | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
teste | cpn | LATIN1 | en_US.ISO-8859-1 | en_US.ISO-8859-1 |
Run Code Online (Sandbox Code Playgroud)
我知道它与类型有关,因为当它被转换时它按预期工作:
teste=> select ' 2'::char > '10';
?column?
----------
f
(1 row)
Run Code Online (Sandbox Code Playgroud)
到底发生了什么?
编辑:
以上所有内容都是在Fedora 13中用8.4.8完成的.但是我在Centos 6中测试了9.04并得到了相同的结果:
select ' 2' > '10';
?column?
----------
t
(1 row)
Run Code Online (Sandbox Code Playgroud)
数据库列表
Name | Owner | Encoding | Collation | Ctype | Access privileges
-----------+------------+-----------+-------------+-------------+-----------------------
cpn | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
Run Code Online (Sandbox Code Playgroud)
新编辑:
这是进一步混淆:
select ' ' > '1';
?column?
----------
f
(1 row)
Run Code Online (Sandbox Code Playgroud)
我认为PostgreSQL会自动尝试找出幕后的类型,而在Linux中它试图摆脱'',一些比较也基于语言环境.
因此,' 2' > '10'
成为'2'>'10'
和比较'2'>'1'
; 它们不相等,所以不需要继续使用字符串的其余部分,并且ascii('2')
大于ascii('1')
,因此它的计算结果为true.
如果它是一个相等运算(例如'22'='22'),它将导致错误,因为Postgres进行逐字节比较.这很重要,因为引擎在进行比较时使用了两种不同的算法.
如果通过类型转换指定类型,则它不会覆盖空间规则(' '=>''
).
另外归功于: #postgresql中的RhodiumToad和Peerce