Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 意外的查询结果_Sql Server_Sql Server 2008_Tsql_Sql Server 2012 - Fatal编程技术网

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有一个奇怪的功能,如果比较两个字符串,并且它们的长度不相等,那么它会将较短的字

为什么我从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 |