Sql server 意外的查询结果
为什么我从sql server获得以下结果Sql server 意外的查询结果,sql-server,sql-server-2008,tsql,sql-server-2012,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 编辑:C3已被回答。每个人的回答都认为'+12=12是字符串串联,但它是一种数学运算。不清楚为什么(而不是如何)“在sql server中转换为0 SQL Server有一个奇怪的功能,如果比较两个字符串,并且它们的长度不相等,那么它会将较短的字
SELECT '' + 12 C1, CONVERT(int, '') C2,
CASE WHEN '' = ' ' THEN 'equal' ELSE 'not equal' END C3
编辑:C3已被回答。每个人的回答都认为
'+12=12
是字符串串联,但它是一种数学运算。不清楚为什么(而不是如何)“
在sql server中转换为0 SQL Server有一个奇怪的功能,如果比较两个字符串,并且它们的长度不相等,那么它会将较短的字符串填充到较长字符串的长度上,然后进行比较。填充字符是一个空格
C1和C2只是将空字符串隐式和显式转换为0。
C1
-此处发生隐式转换,空字符串转换为0。这解释了为什么您会得到12
(`0+12)
C2
-将'
显式转换为整数将导致0
。有点艺术性,但这就是它的工作原理(并且可能会发生变化——据我所知,这没有记录在案,如果有人知道其他情况,请纠正我)
C3
-请参见-基本上,在比较不同长度的字符串时,先用空格填充短字符串,然后再填充长字符串的长度。这或多或少是预期的行为。从SQL(ISO/ANSI)标准的副本:
两个字符串表达式的比较取决于用于比较的排序规则。比较长度不等的值时,如果比较的排序规则具有无PAD
特性,且较短的值等于较长值的某个前缀,则认为较短的值小于较长的值。如果比较的排序规则具有PAD SPACE
特性,则出于比较的目的,通过将右侧的s串联起来,将较短的值有效地扩展到较长的值的长度
现在,大多数数据库管理系统都实现了字符串比较,但略有不同。在SQL_Server和MySQL中,您会发现'
、'
、'
和'
(带0、1、2和3空格的字符串)都是相等的,无论它们是定义为VARCHAR
还是CHAR
在Postges中,如果它们是VARCHAR
,则它们都是不相等的;如果CHAR
,则它们是相等的(因此VARCHAR
列中没有填充)。如果其中一个是VARCHAR和一个CHAR,那么它们是相等的,所以我猜填充是在比较之前完成的
Oracle与Postgres类似,它有一个额外的特点,即空字符串'
的行为(几乎所有地方)都是NULL
。因此,当您将其与带有一个或多个空格的字符串(或与字符串本身)进行比较时,结果既不是真的也不是假的,而是未知的。Oracle还有一个区别,如果一个字符串定义为VARCHAR
,另一个定义为CHAR
,那么比较就相当复杂了。从测试中,我假设在这种情况下,只有CHAR
被填充到其(定义的数据类型)长度,然后与未添加的VARCHAR
进行比较
您可以在中检查(所有4个DBMS)您所说的是
'=''
(与单个空格相比为空字符串)?但是,由于您使用'
有三种不同的情况,因此不清楚您是否找到了'+12
,转换(int')的结果
或'='
是意外的。其中两个我会期待,一个我不会,但另一个可能有其他的期望。我要求澄清-只显示您询问的代码-额外的内容只是掩盖了问题。@Oded:我测试了自己是否可以将空字符串转换为int,这就是c2存在的原因。一个是隐式的,一个是显式的。我不想混淆。我知道这是你测试的一部分,但不应该是问题的一部分……好的。现在还不清楚这三个人是否都不被期待。。。就像我说的,对我来说,两个是。谢谢,C3的结果很清楚,但不确定为什么会这样做。C1/C2?相反<代码>+在这里不作为字符串串联
。它是数学运算符。请检查一下。@Kaf:你是对的,我错了。这种情况实际上更复杂,但在这种情况下你是对的。某些转换在某些系统上以某些方式工作,可能在标准中没有明确规定。例如,在Oracle上,空字符串被视为NULL,这就是C编程语言中空字符串的处理方式。如果标准中没有具体规定,供应商可以自由地根据自己的选择实施。空字符串在C中被视为null?我第一次听说这个。即使这是真的——我对此表示怀疑——C中的NULL与SQL中的NULL
值有很大的不同。事实上,众所周知,C中的字符串只是一个字符数组,末尾有一个零字节。因此,空字符串只是一个零字节,因此等于0。C中的NULL被定义为0。我并不反对C和SQL的不同,只是指出了Oracle的功能。您指的是空字符(\0
,1字节)。我想到的是空指针(通常是4个字节)。
--Results
| C1 | C2 | C3 |
-------------------
| 12 | 0 | equal |