整数作为SQL别名不会错误,但给出不正确的结果
我正在研究一些SQL代码,其中发件人误认为表的别名,这是字母l,但他们已输入数字1。整数作为SQL别名不会错误,但给出不正确的结果
即使这个错误已经使代码仍然运行。
下面是代码
SELECT l.[Name]
,l.Address
,1.Postcode
FROM List l
与错误是代码的1.Postcode
代替l.Postcode
结果的一个例子与邮编列全1出来,如下
如果错误是使用t.Postcode
那么它呢ld给出错误
无法绑定多部分标识符“t.Postcode”。
,而不是示数1.Postcode
但被视为1 AS Postcode
更正行l.Postcode
给出正确的数据,如下
所以我的问题是为什么不行1.Postcode
错误?
你的语法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 ]
正如你所看到的,考虑1
和Postcode
之间的点作为分隔符,1
不是table_name, view_name, table_alias, nor a udt_column_name
,所以它仍然只是method_name
和expression
。
但1.Postcode
不能是method_name
(cannot start with a number),所以你的情况是expression [ [ AS ] column_alias ]
其中:
表达
是一个常数,函数,列名,常量的任意组合,以及由操作员或操作员或子查询连接的功能。
嗯..再次,1
不能是函数也不是科拉姆名(cannot start with a number),所以它MUST是constant。
第一个字符1
是一个不同于0的数字,所以它不能只是一个bit, integer, decimal or float constant
,但第二个字符.
只限制为十进制和浮点数常量。
.
的我们有P
之后,它不是一个号码..并且它不是E
或e
(其表示浮子常数),所以我们已经找到了十进制常量。
以下是不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
请添加数据库标签。我在sql服务器中进行了重新编译,很有趣。 – HoneyBadger
SQL Server 2008 R2,只是添加了标签。这很奇怪,不是。 – ChrisM
我在sql server 2014中测试过。是的,它很奇怪。 – HoneyBadger