2016-03-14 30 views
8

Tôi tự hỏi tại sao nó hoạt động và tại sao nó không trả lại một lỗi:Parsing SQL Server số chữ với dấu gạch dưới

SELECT 2015_11 

Kết quả:

╔══════╗ 
║ _11 ║ 
╠══════╣ 
║ 2015 ║ 
╚══════╝ 

trường hợp thứ hai:

SELECT 2.1_a 

╔═════╗ 
║ _a ║ 
╠═════╣ 
║ 2.1 ║ 
╚═════╝ 

Kiểm tra siêu dữ liệu:

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)  ║ 
╚══════╩══════════════════╝ 

Trong khi định bắt đầu bằng chữ cái cư xử như tôi nghĩ rằng nó nên:

SELECT a_11 
-- Invalid column name 'a_11'. 

LiveDemo

Trả lời

9

xử lý SQL truy vấn như

SELECT 2015_11 

như

SELECT 2015 _11 

đó là phím tắt cho

SELECT 2015 AS [_11] 

SQL Server hy vọng tên cột để làm theo một số quy tắc quy ước đặt tên được nêu chi tiết trong này MSDN link

The names of variables, functions, and stored procedures must comply with the following rules for Transact-SQL identifiers. The first character must be one of the following:

  1. A letter as defined by the Unicode Standard 3.2. The Unicode definition of letters includes Latin characters from a through z, from A through Z, and also letter characters from other languages.
  2. The underscore (_), at sign (@), or number sign (#).

    Certain symbols at the beginning of an identifier have special meaning in SQL Server. A regular identifier that starts with the at sign always denotes a local variable or parameter and cannot be used as the name of any other type of object. An identifier that starts with a number sign denotes a temporary table or procedure. An identifier that starts with double number signs (##) denotes a global temporary object. Although the number sign or double number sign characters can be used to begin the names of other types of objects, we do not recommend this practice.

Some Transact-SQL functions have names that start with double at signs (@@). To avoid confusion with these functions, you should not use names that start with @@.

Ngoài ra cú pháp cho SELECT theo MSDN là như

SELECT [ ALL | DISTINCT ] [ TOP (expression) [ 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]) } ] | expression [ [ AS ] column_alias ] } | column_alias = expression } [ ,...n ]

Trong trường hợp này trình phân tích cú pháp SQL đầu tiên kiểm tra tên bảng và sau đó là tên cột, Danh tính và hàng rào, v.v. cho đến khi nó chạm kết quả phù hợp với

| biểu [[AS] column_alias]

Sau đó nó đọc giá trị văn chương đến ký tự gạch dưới đó là khi nó nhận ra rằng đen phải đã kết thúc và bắt đầu phân tích các nhân vật sau này như Column_alias không như rõ ràng AS

Để xác minh này thử đoạn mã sau trong SQL server

SELECT 2015AS _11 

Điều này sẽ tạo ra kết quả tương tự như

SELECT 2015_11 

Ngoài ra để xác minh những gì tôi chỉ viết ở trên nhìn thấy ảnh chụp màn hình từ SSMS mà không một mã làm nổi bật trên AS

enter image description here

Trong ví dụ đầu tiên của bạn năm 2015 là số nguyên nghĩa đen và trong ví dụ thứ hai 2.1 là chữ số thập phân

Trong ví dụ thứ ba của bạn a không phải là chữ hợp lệ. Nếu bạn cố gắng

SELECT 'a'_8 

này sẽ cung cấp cho bạn kết quả như

╔═════╗ 
║ _8 ║ 
╠═════╣ 
║ a ║ 
╚═════╝ 

PS: Bạn sẽ thấy rằng làm việc này khá nhiều theo cùng một cách với # cũng

Vì vậy SELECT 2015#11 sẽ cung cấp kết quả tương tự

╔══════╗ 
║ #11 ║ 
╠══════╣ 
║ 2015 ║ 
╚══════╝ 
+0

Bạn có thể cung cấp một số tài liệu về hành vi này không? Tôi đồng ý rằng nó có thể là trường hợp, nhưng nó nên được đề cập ở đâu đó. – lad2025

+0

Dấu gạch dưới kích hoạt "mã thông báo tiếp theo" của máy quét. I.e năm 2015 theo sau (mất khoảng trắng) và sau đó _11 (bí danh cột hợp lệ.) – jarlh

3

Để und hãy hiểu những gì đang xảy ra, bạn cần phải hiểu những gì SQL Server chấp nhận là định danh. Có rất nhiều quy tắc, được ghi thành tài liệu here. Nhưng, điều quan trọng là:

The first character must be one of the following:

  1. A letter as defined by the Unicode Standard 3.2. The Unicode definition of letters includes Latin characters from a through z, from A through Z, and also letter characters from other languages.

  2. The underscore (_), at sign (@), or number sign (#).

Điểm quan trọng là khi trình phân tích cú pháp SQL Server gặp một chữ số, nó tự nói: "Đây là số". Khi nó chạm vào dấu gạch dưới, nó nói "Vâng, không có số lượng nhiều hơn, phải bắt đầu cái gì khác". Các phân tích cú pháp công nhận các thành phần thứ hai như một định danh hợp lệ, vì vậy đây được coi là:

select 2015 _11 

đó là một bí danh cột, ngay cả khi không as.

Các vấn đề liên quan