2017-10-10 93 views
3

我正在研究一些SQL代码,其中发件人误认为表的别名,这是字母l,但他们已输入数字1。整数作为SQL别名不会错误,但给出不正确的结果

即使这个错误已经使代码仍然运行。

下面是代码

SELECT l.[Name] 
     ,l.Address 
     ,1.Postcode 
FROM List l 

与错误是代码的1.Postcode代替l.Postcode

结果的一个例子与邮编列全1出来,如下

Incorrect

如果错误是使用t.Postcode那么它呢ld给出错误

无法绑定多部分标识符“t.Postcode”。

,而不是示数1.Postcode但被视为1 AS Postcode

更正行l.Postcode给出正确的数据,如下

Correct

所以我的问题是为什么不行1.Postcode错误?

+0

请添加数据库标签。我在sql服务器中进行了重新编译,很有趣。 – HoneyBadger

+0

SQL Server 2008 R2,只是添加了标签。这很奇怪,不是。 – ChrisM

+0

我在sql server 2014中测试过。是的,它很奇怪。 – HoneyBadger

回答

2

你的语法1.Postcode由SQL服务器视为+1.0 AS Postcode

有一种误解,抛出任何错误,因为没有错误抛出,并给出正确的结果......这句法..

这里的主要问题是列值和列别名之间的空间不是必需的,在某些情况下,可以省略。

SELECT来自微软的文档:

SELECT [ ALL | DISTINCT ] 
[ TOP (expression) [ PERCENT ] [ WITH TIES ] ] 
<select_list> 
<select_list> ::= 
    { 
     * 
     | { table_name | view_name | table_alias }.* 
     | { 
      [ { table_name | view_name | table_alias }. ] 
       { column_name | $IDENTITY | $ROWGUID } 
      | udt_column_name [ { . | :: } { { property_name | field_name } 
      | method_name (argument [ ,...n]) } ] 
      | expression 
      [ [ AS ] column_alias ] 
     } 
     | column_alias = expression 
    } [ ,...n ] 

正如你所看到的,考虑1Postcode之间的点作为分隔符,1不是table_name, view_name, table_alias, nor a udt_column_name,所以它仍然只是method_nameexpression
1.Postcode不能是method_namecannot start with a number),所以你的情况是expression [ [ AS ] column_alias ]

其中:

表达
是一个常数,函数,列名,常量的任意组合,以及由操作员或操作员或子查询连接的功能。

嗯..再次,1不能是函数也不是科拉姆名(cannot start with a number),所以它MUSTconstant

第一个字符1是一个不同于0的数字,所以它不能只是一个bit, integer, decimal or float constant,但第二个字符.只限制为十进制和浮点数常量。

.的我们有P之后,它不是一个号码..并且它不是Ee(其表示浮子常数),所以我们已经找到了十进制常量。

以下是不AS(请注意空白AS后),所以它可能是列别名,Postcode是一个有效的列别名..所以我们有我们的新列,它的值是1(准确地说1.0)和它的名字是Postcode

看看这些例子并享受:

select 
    1.Postcode_decimal, -- 1.0 AS Postcode_decimal 
    1.ePostcode_float, -- 1.0E0 AS Postcode_float 
    1.asPostcode_decimal, -- 1.0 AS asPostcode_decimal 
    1.as PostcodeAS_decimal, -- 1.0 AS PostcodeAS_decimal 
    1Postcode_int, -- 1 AS Postcode_int 
    1.+1.Postcode_expression, -- (1.0 + 1.0) AS Postcode_expression 
    1.%1.+1+0.-.0/.1e-1Postcode_more_complex_expr, -- (1.0 % 1.0) + 1 + (0.0/0.1E-1) AS Postcode_more_complex_expr 
    0xPostcode_varbin, -- 0x00 as Postcode_varbin 
    3.5[3.5], -- 3.5 AS [3.5] 
    'Hello'Postcode_varchar, 
    '1.0'[1.0], -- value is varchar, name is '1.0' 
    -- you can single quote an alias 
    22'Postcode_int2', 
    22'2.2', 
    -- but beware of two single quotes are treated as one literal single quote.. 
    'Hello''Postcode_varchar'_ -- yes, the underscore can be an identifier.. 
into 
    #test_alias 

SELECT * FROM #test_alias 

select column_ordinal, name, is_nullable, system_type_name, max_length, precision, source_column 
from sys.dm_exec_describe_first_result_set(N'SELECT * FROM #test_alias',null,1) 

drop table #test_alias 

输出:

Postcode_decimal Postcode_float asPostcode_decimal PostcodeAS_decimal Postcode_int Postcode_expression Postcode_more_complex_expr Postcode_varbin Postcode_varchar 1.0 Postcode_int2 2.2 _      3.5 
1     1    1     1     1    2     1       0x    Hello    1.0 22    22 Hello'Postcode_varchar 3.5 

column_ordinal name      is_nullable system_type_name max_length precision 
1    Postcode_decimal   0   numeric(1,0)  5   1   
2    Postcode_float    0   float    8   53   
3    asPostcode_decimal   0   numeric(1,0)  5   1   
4    PostcodeAS_decimal   0   numeric(1,0)  5   1   
5    Postcode_int    0   int     4   10   
6    Postcode_expression   1   numeric(2,0)  5   2   
7    Postcode_more_complex_expr 1   float    8   53   
8    Postcode_varbin    0   varbinary(1)  1   0   
9    Postcode_varchar   0   varchar(5)   5   0   
10    1.0       0   varchar(3)   3   0   
11    Postcode_int2    0   int     4   10   
12    2.2       0   int     4   10   
13    _       0   varchar(22)   22   0   
14    3.5       0   numeric(2,1)  5   2   
+0

谢谢,我很喜欢这个例子 – ChrisM

+1

很高兴听到:) – MtwStark

相关问题