2

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

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

Sql-Server 小提琴演示

--Results
| C1 | C2 |    C3 |
-------------------
| 12 |  0 | equal |

编辑: C3 已回答。每个人都回答认为'' + 12 = 12是字符串连接,但它是一种数学运算。目前尚不清楚为什么(不是如何)''在 sql-server 中转换为 0。

4

3 回答 3

9

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

两个字符串表达式的比较取决于用于比较的排序规则。当比较长度不等的值时,如果用于比较的排序规则具有NO PAD特征并且较短的值等于较长值的某个前缀,则认为较短的值小于较长的值。如果用于比较的排序规则具有PAD SPACE特征,则为了比较的目的,通过将右侧的 <space> 串联起来,将较短的值有效地扩展到较长的值

现在,大多数 DBMS 已经实现了略有不同的字符串比较。在 SQL_Server 和 MySQL 中,你会发现'',' '和(0, 1, 2'  ''   '3 个空格的字符串) 都是相等的,无论它们是否定义为VARCHARor CHAR

在 Postges 中,如果它们相等,它们都是不相等的,VARCHAR但如果相等(因此在列CHAR中没有填充)。VARCHAR如果其中一个是 VARCHAR 和一个 CHAR,那么它们是相等的,所以我猜想在比较之前填充。

Oracle 与 Postgres 类似,但空字符串的''行为(几乎无处不在)为NULL. 因此,当您将其与具有一个或多个空格的字符串(或与自身)进行比较时,结果既不是 True 也不是 False,而是UNKNOWN. Oracle还有一个区别,如果一个字符串定义为VARCHAR,另一个字符串定义为CHAR,比较比较复杂。从测试中,我假设仅CHAR在这种情况下被填充,直到它们的(定义的数据类型)长度,然后与 unpadded 进行比较VARCHAR

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

于 2013-02-24T19:34:54.353 回答
4

C1- 这里发生了隐式转换,空字符串被转换为 0。这解释了为什么你得到12(`0 + 12)。

C2- 显式转换''为整数会导致0. 有点艺术,但这就是它的工作方式(并且可能会改变 - 据我所知,这没有记录,如果有人知道,请纠正我)。

C3- 查看muhmud 的答案- 基本上在比较不同长度的字符串时,较短的字符串首先用空格填充到较长的长度。

于 2013-02-24T19:27:57.120 回答
3

SQL Server 有一个奇怪的特性,如果比较两个字符串,并且它们的长度不相等,那么它会将较短的字符串填充到较长字符串的长度,然后进行比较。填充字符是一个空格。http://support.microsoft.com/kb/316626

C1 和 C2 只是将空字符串隐式和显式转换为 0。

于 2013-02-24T19:04:47.203 回答