2017-10-10 91 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

相關問題