sql-server - 意外的查询结果

标签 sql-server sql-server-2008 tsql sql-server-2012

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

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

Sql-Server Fiddle demo

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

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

最佳答案

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

The comparison of two character string expressions depends on the collation used for the comparison. When values of unequal length are compared, if the collation for the comparison has the NO PAD characteristic and the shorter value is equal to some prefix of the longer value, then the shorter value is considered less than the longer value. If the collation for the comparison has the PAD SPACE characteristic, for the purposes of the comparison, the shorter value is effectively extended to the length of the longer by concatenation of <space>s on the right.

现在,大多数 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)

关于sql-server - 意外的查询结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15055360/

相关文章:

tsql - 如何使用 Transact SQL 将 JPEG 插入到图像类型的 SQL Server 2000 数据库字段中

sql-server - 将keras模型保存到数据库

.net - 将 blob 存储在 SQL Server 中而不将 blob 读入内存

sql-server - SQL Server : How to select all days in a date range even if no data exists for some days

SQL - 另一个 Select 语句的 Where 子句?

sql-server - SQL Server 中的临时表 - 如果查询需要很长时间才能完成,则会发生错误

sql-server - 有没有办法在字符串的开头放置一个不可见的字符来更改其排序顺序?

sql-server - SSRS 2008 自动换行问题

sql - MSSQL 通过 ID 从多列中获取最大值

sql - 从 SQL 中的另一个表更新表给出了意外结果