意外的查询结果

Kaf*_*Kaf 2 t-sql sql-server sql-server-2008 sql-server-2012

为什么我从sql-server获得以下结果?

SELECT '' + 12 C1, CONVERT(int, '') C2,
       CASE WHEN '' = ' ' THEN 'equal' ELSE 'not equal' END C3
Run Code Online (Sandbox Code Playgroud)

Sql-Server小提琴演示

--Results
| C1 | C2 |    C3 |
-------------------
| 12 |  0 | equal |
Run Code Online (Sandbox Code Playgroud)

编辑: C3已被回答.每个人都回答的想法'' + 12 = 12是字符串连接,但这是一个数学运算.为什么(目前尚不清楚不是如何),''在SQL服务器转换为0.

ype*_*eᵀᴹ 9

这或多或少是预期的行为.从SQL(ISO/ANSI)标准的副本:

两个字符串表达式的比较取决于用于比较的排序规则.当比较不等长度的值时,如果比较的核对具有NO PAD特征并且较短的值等于较长值的某个前缀,则认为较短的值小于较长的值.如果比较的校对具有PAD SPACE特征,则为了进行比较,通过在右侧连接<space> s,较短的值有效地扩展到较长的长度.

现在,大多数DBMS都实现了字符串比较,略有不同.在SQL_SERVER和MySQL,你会发现'',' ','  ''   '(0,1,2和3位字符串)都是平等的,如果他们被定义为,无论VARCHARCHAR.

在Postges中,如果它们相等则它们都是不VARCHAR相等的CHAR(因此在VARCHAR列中没有填充).如果其中一个是VARCHAR和一个CHAR,那么它们被发现相等,所以我想填充是在比较之前完成的.

Oracle类似于Postgres,具有额外的特性,即空字符串''表现为(几乎无处不在)NULL.因此,当您将其与具有一个或多个空格(或其自身)的字符串进行比较时,结果既不是True也不是False UNKNOWN.Oracle有一个更差,如果一个串被定义为VARCHAR和其他作为CHAR,比较是相当复杂的.从测试开始,我假设只CHAR在这种情况下填充,直到它们(定义的数据类型)长度,然后与未填充的数据进行比较VARCHAR.

您可以在SQL-Fiddle中检查(所有4个DBMS)