为什么我从sql-server获得以下结果?
SELECT '' + 12 C1, CONVERT(int, '') C2,
CASE WHEN '' = ' ' THEN 'equal' ELSE 'not equal' END C3
--Results
| C1 | C2 | C3 |
-------------------
| 12 | 0 | equal |
编辑: C3已被回答。每个人都回答认为'' + 12 = 12
是字符串连接,但这是一个数学运算。目前尚不清楚为什么( NOT how)''
在sql-server中转换为0。
答案 0 :(得分:9)
这或多或少是预期的行为。从SQL(ISO / ANSI)标准的副本:
两个字符串表达式的比较取决于用于比较的排序规则。当比较不等长度的值时,如果比较的核对具有
NO PAD
特征并且较短的值等于较长值的某个前缀,则认为较短的值小于较长的值。如果比较的排序规则具有PAD SPACE
特征,则出于比较的目的, 通过连接< space>来将较短的值有效地扩展到较长的长度。右 即可。
现在,大多数DBMS都实现了字符串比较,略有不同。在SQL_Server和MySQL中,您会发现''
,' '
,' '
和' '
(带有0,1,2和3个空格的字符串)都相等,没有如果它们被定义为VARCHAR
或CHAR
。
在Postges中,如果它们是VARCHAR
,则它们都是不相等的,但如果CHAR
则相等(因此VARCHAR
列中没有填充)。如果其中一个是VARCHAR和一个CHAR,那么它们被发现是相等的,所以我想填充是在比较之前完成的。
Oracle类似于Postgres,具有额外的特性,即空字符串''
的行为(几乎无处不在)为NULL
。因此,当您将其与具有一个或多个空格(或自身)的字符串进行比较时,结果既不是True也不是False,而是UNKNOWN
。 Oracle还有一个区别,如果一个字符串定义为VARCHAR
而另一个字符串定义为CHAR
,则比较相当复杂。从测试开始,我假设在这种情况下只填充CHAR
,直到它们(定义的数据类型)长度,然后与未填充的VARCHAR
进行比较。
您可以在 SQL-Fiddle
中查看(全部4个DBMS)答案 1 :(得分:4)
C1
- 这里发生隐式转换,空字符串转换为0.这就解释了为什么你得到12
(`0 + 12)。
C2
- 将''
显式转换为整数会产生0
。有点画像,但这就是它的工作原理(并且可能会改变 - 据我所知这没有记录,如果有人不知道,请纠正我。)
C3
- 请参阅the answer by muhmud - 基本上在比较不同长度的字符串时,较短的字符串首先用空格填充长度的长度。
答案 2 :(得分:3)
SQL Server有一个奇怪的特性,如果比较两个字符串,并且它们长度不相等,那么它会将较短的字符串填充到较长字符串的长度,然后比较它们。填充字符是一个空格。 http://support.microsoft.com/kb/316626
C1& C2只是隐含的&将空字符串显式转换为0。