SQL Server: 非数字字符串上的+(一元)运算符

4

我很惊讶!以下陈述在SQL SERVER中是有效的:

SELECT  +'ABCDEF'

SQL Server是否将+定义为字符串类型的一元运算符?

1个回答

6
这是我对这个问题的答案(请看结尾的更新部分):
没有这样的一元运算符定义在字符串表达式上。这可能是一个错误。
解释:
给定的语句是有效的,它生成以下结果:
(No column name) 
----------------
ABCDEF
(1 row(s) affected)

这相当于在不使用 + 符号的情况下执行 SELECT 语句:

SELECT  'ABCDEF'

编译没有出现任何错误,事实上成功执行,给人的印象是+作为给定字符串上的一元操作符在运行。然而,在官方的T-SQL文档中,并没有提到这样的操作符。事实上,在String Operators这个章节中,+出现在两个字符串操作中,分别是+(字符串连接)+=(字符串连接);但是都不是一元操作符。此外,在Unary Operators这个章节中,介绍了三个操作符,只有一个是+(正号)操作符。然而,对于似乎相关的这一个操作符,很快就变得清楚,这个操作符也与非数值字符串值无关,因为+(正号)操作符的解释明确说明,该操作符仅适用于数值表达式:“返回数值表达式的值(一元操作符)”。
也许,这个操作符的作用是成功接受那些被成功地评估为数字的字符串值,比如在这里使用的那个字符串:
SELECT  +'12345'+1

执行上述语句时,输出的数字是给定字符串作为数字求值和添加到其中的数值(此处为1,但显然可以是任何其他数额)的总和。
(No column name) 
----------------
12346
(1 row(s) affected)

然而,我怀疑这个解释不正确,因为它引发了以下问题:
首先,如果我们接受这个解释是真的,那么我们可以得出这样的结论:表达式 +'12345' 被计算为数字。如果是这样,那么为什么这些数字会出现在与字符串相关的函数中,例如 DATALENGTHLEN 等等。你可能会看到这样的语句:
  SELECT  DATALENGTH(+'12345')

是相当有效的,它的结果如下:

 (No column name) 
----------------
5
(1 row(s) affected)

这意味着+'12345'被解析为字符串而不是数字。这是如何解释的?

其次,类似于以下语句中的带有-运算符:

 `SELECT  -'ABCDE'` 

甚至是这个:

`SELECT  -'12345'` 

生成以下错误:
Invalid operator for data type. Operator equals minus, type equals varchar.

为什么当使用+操作符与非数字字符串值错误地结合时,不会生成类似情况的错误?

因此,这两个问题阻止我接受这是文档中引入的相同的+(一元)操作符的解释。由于在任何其他地方都没有提到它,可能是有意添加到语言中的。也可能是一个bug。

当我们看到像这样的语句时,问题似乎更加严重,因为没有生成错误:

SELECT ++++++++'ABCDE'

我不知道是否还有其他编程语言接受这种语句,但如果有的话,知道它们使用+(一元)操作符来操作字符串的目的会很好。我无法想象它的任何用途!
更新:
在这里,它说这是早期版本中的一个错误,但由于向后兼容性,不会修复:
经过一些调查,这种行为是按设计进行的,因为+是一元操作符。所以解析器接受“+”,在这种情况下'+'被忽略。 更改此行为会对向后兼容性产生很多影响,所以我们不打算更改它,并且修复会为应用程序代码引入不必要的更改。

2
根据https://connect.microsoft.com/SQLServer/feedback/details/718176/concatenation-operator-not-working-properly,字符串上有一元运算符。 - Martin Smith
你的意思是这个吗?“经过一些调查,这种行为是由于+是一元运算符而设计的。因此解析器接受“+ <表达式>”,在这种情况下'+'被简单地忽略了。 改变这种行为会带来很多向后兼容性的影响,所以我们不打算改变它,修复将为应用程序代码引入不必要的更改。” - RGO
是的。那是在你引用的另一个回复之后发布的,因此表明至少在微软看来,这是“按设计”而不是错误。该项被标记为“按设计”而不是“不修复”。 - Martin Smith
是的,他们说这是早期版本中的一个错误,将不会在未来版本中修复。我会更新帖子。然而,他们在一些我不明白的情况下使用它,比如这里的例子B:http://msdn.microsoft.com/en-us/library/ms187323.aspx。这就是我遇到问题的地方。 - RGO
在示例B中,可以推断出他们要么不应该包括逗号,要么不必理会前导的“+”,因为它是多余的。 - Martin Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接