我想知道它为什么会起作用以及为什么它不会返回错误:
SELECT 2015_11
结果:
╔══════╗
║ _11 ║
╠══════╣
║ 2015 ║
╚══════╝
第二种情况:
SELECT 2.1_a
╔═════╗
║ _a ║
╠═════╣
║ 2.1 ║
╚═════╝
检查元数据:
SELECT name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT 2015_11', NULL, 0)
UNION ALL
SELECT name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT 3.2_a', NULL, 0)
╔══════╦══════════════════╗
║ name ║ system_type_name ║
╠══════╬══════════════════╣
║ _11 ║ int ║
║ _a ║ numeric(2,1) ║
╚══════╩══════════════════╝
虽然以字母开头的标识符表现得像我认为的那样:
SELECT a_11
-- Invalid column name 'a_11'.
的 LiveDemo
答案 0 :(得分:9)
SQL将查询视为
SELECT 2015_11
as
SELECT 2015 _11
是
的捷径SELECT 2015 AS [_11]
SQL Server期望列名遵循一些命名约定规则,详见此MSDN link
变量,函数和存储过程的名称必须符合以下Transact-SQL标识符规则。 第一个字符必须是以下之一:
- Unicode标准3.2定义的字母。字母的Unicode定义包括从a到z的拉丁字符 A到Z,还有其他语言的字母。
- 醇>
下划线(_),符号(@)或数字符号(#)。
标识符开头的某些符号在SQL Server中具有特殊含义。以at开头的常规标识符 sign总是表示局部变量或参数,不能使用 作为任何其他类型对象的名称。开始的标识符 带数字符号表示临时表或过程。一个 以双数字符号(##)开头的标识符表示全局 临时对象。虽然数字符号或双数字符号 字符可用于开始其他类型对象的名称, 我们不推荐这种做法。
某些Transact-SQL函数的名称以符号(@@)的double开头。为避免与这些功能混淆,你不应该这样做 使用以@@。开头的名称。
SELECT
的语法与MSDN类似
SELECT [ALL | DISTINCT] [TOP(表达式)[PERCENT] [WITH TIES ]] :: = { * | {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])}] |表达 [[AS] column_alias] } | column_alias = expression } [,... n]
在这种情况下,SQL解析器首先检查表名,然后检查列名,Identity和rowguid,依此类推,直到它与
匹配。<强> |表达[[AS] column_alias]
然后读取字面值直到下划线字符,当它意识到文字必须已经结束并开始将后面的字符解析为 Column_alias 而没有明确的AS
要验证此操作,请尝试在SQL Server中执行以下代码
SELECT 2015AS _11
这将产生与
相同的结果SELECT 2015_11
另外要验证我刚才写的内容,请参阅SSMS的截图,该截图在AS
在您的第一个示例中,2015是整数字面值,在第二个示例中,2.1是十进制字面值
在第三个例子中,a不是有效的文字。如果你试试
SELECT 'a'_8
这会给你一些像
的结果╔═════╗
║ _8 ║
╠═════╣
║ a ║
╚═════╝
PS :你会发现这与#以及
的工作方式大致相同所以SELECT 2015#11
会给出类似的结果
╔══════╗
║ #11 ║
╠══════╣
║ 2015 ║
╚══════╝
答案 1 :(得分:3)
要了解发生的情况,您需要了解SQL Server接受的标识符。有许多规则,记录在案here。但是,重要的是:
第一个字符必须是以下之一:
Unicode标准3.2定义的字母。字母的Unicode定义包括从a到z的拉丁字符 A到Z,还有其他语言的字母。
- 醇>
下划线(_),符号(@)或数字符号(#)。
重要的一点是,当SQL Server解析器遇到一个数字时,它会对自己说:&#34;这是一个数字&#34;。当它击中下划线时,它会说&#34;嗯,没有更多的数字,必须开始别的东西&#34;。解析器将第二个组件识别为有效标识符,因此将其视为:
select 2015 _11
用于列别名,即使没有as
。