Chà, số nhận dạng luôn là Unicode / NVARCHAR
, vì vậy về mặt kỹ thuật, bạn không thể tạo bất cứ thứ gì không có tên Unicode.
Vấn đề bạn gặp phải ở đây hoàn toàn là do việc phân loại (các) nhân vật đang được sử dụng. Các quy tắc cho định danh thông thường (tức là không phân cách) là:
- Chữ cái đầu tiên phải là:
- Một chữ cái theo định nghĩa của Tiêu chuẩn Unicode 3.2.
- gạch dưới (_), tại dấu (@) hoặc ký hiệu số (#)
- Các chữ cái tiếp theo có thể là:
- Các chữ cái như được định nghĩa trong Tiêu chuẩn Unicode 3.2.
- Số thập phân từ tiếng Latin cơ bản hoặc chữ viết quốc gia khác.
- gạch dưới (_), tại ký hiệu (@), ký hiệu số (#) hoặc ký hiệu đô la ($)
- Không gian nhúng hoặc ký tự đặc biệt không được phép.
- Nhân vật bổ sung không được phép.
Tôi nhấn mạnh các quy tắc duy nhất quan trọng trong bối cảnh này. Lý do mà các quy tắc "Chữ cái đầu tiên" không liên quan ở đây là vì chữ cái đầu tiên trong tất cả các biến và tham số cục bộ luôn luôn là "tại dấu" @
.
Và rõ ràng: những gì được coi là "chữ cái" và những gì được coi là "chữ số thập phân" dựa trên các thuộc tính mà mỗi ký tự được gán trong Cơ sở dữ liệu Ký tự Unicode. Unicode gán nhiều thuộc tính cho mỗi ký tự, chẳng hạn như: is_uppercase, is_lowercase, is_digit, is_decimal, is_combining, v.v. Các thuộc tính này thường được sử dụng trong Biểu thức chính quy để khớp với "dấu câu", v.v. Ví dụ: \p{Lu}
khớp với bất kỳ chữ in hoa nào (trên tất cả các ngôn ngữ / tập lệnh) và \p{IsDingbats}
khớp với bất kỳ ký tự "Đinh lăng" nào.
Vì vậy, trong nỗ lực của bạn để làm:
DECLARE @¯\_(ツ)_/¯ INT;
chỉ các ký tự _
(gạch dưới hoặc "dòng thấp") và ツ
(Katakana Letter Tu U + 30C4) phù hợp với các quy tắc đó. Bây giờ, tất cả các ký tự trong ¯\_(ツ)_/¯
đều ổn đối với các định danh được phân tách, nhưng thật không may là dường như tên biến / tham số và GOTO
nhãn không thể được phân định (mặc dù tên con trỏ có thể được).
Vì vậy, đối với tên biến / tham số, vì chúng không thể được phân tách, bạn bị mắc kẹt khi chỉ sử dụng các ký tự đủ điều kiện là "chữ cái" hoặc "chữ số thập phân" như Unicode 3.2 (theo tài liệu; tôi cần kiểm tra nếu phân loại đã được cập nhật cho các phiên bản Unicode mới hơn do phân loại được xử lý khác với trọng số sắp xếp).
TUY NHIÊN # 1 , mọi thứ không đơn giản như mong muốn. Bây giờ tôi đã có thể hoàn thành nghiên cứu của mình và nhận thấy rằng định nghĩa đã nêu không hoàn toàn chính xác. Định nghĩa chính xác (và có thể kiểm chứng) về các ký tự hợp lệ cho các định danh thông thường là:
Nhân vật đầu tiên:
- Có thể là bất cứ thứ gì được phân loại trong Unicode 3.2 là "ID_Start" (bao gồm "Chữ cái" nhưng cũng có "ký tự số giống chữ")
- Có thể là
_
(dòng thấp / gạch dưới) hoặc _
(dòng thấp toàn băng thông)
- Có thể
@
, nhưng chỉ cho các biến / tham số
- Có thể
#
, nhưng nếu đối tượng ràng buộc lược đồ, thì chỉ đối với Bảng và Thủ tục lưu trữ (trong trường hợp đó chúng chỉ ra rằng đối tượng là tạm thời)
Nhân vật tiếp theo:
- Có thể là bất cứ thứ gì được phân loại trong Unicode 3.2 là "ID_Continue" (bao gồm các số "thập phân", nhưng cũng có thể là "dấu cách kết hợp và không dấu cách" và "dấu chấm câu kết nối")
- Có thể
@
, #
hoặc$
- Có thể là bất kỳ trong số 26 ký tự được phân loại trong Unicode 3.2 dưới dạng các ký tự điều khiển định dạng
(sự thật thú vị: "ID" trong "ID_Start" và "ID_Continue" là viết tắt của "Định danh". Hãy tưởng tượng rằng ;-)
Theo "Tiện ích Unicode: Unicodeset":
Ký tự bắt đầu hợp lệ
[: Tuổi = 3,2:] & [: ID_Start = Có:]
-- Test one "Letter" from each of 10+ languages, as of Unicode 3.2
DECLARE @ᔠᑥᑒᏯשፙᇏᆇᄳᄈლဪඤaൌgೋӁウﺲﶨ INT;
-- works
-- Test a Supplementary Character that is a "Letter" as of Unicode 3.2
DECLARE @𝒲 INT;-- Mathematical Script Capital W (U+1D4B2)
/*
Msg 102, Level 15, State 1, Line XXXXX
Incorrect syntax near '0xd835'.
*/
Ký tự tiếp tục hợp lệ
[: Tuổi = 3,2:] & [: ID_Continue = Có:]
-- Test various decimal numbers, but none are Supplementary Characters
DECLARE @६৮༦൯௫୫9 INT;
-- works (including some Hebrew and Arabic, which are right-to-left languages)
-- Test a Supplementary Character that is a "decimal" number as of Unicode 3.2
DECLARE @𝟜 INT; -- MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR (U+1D7DC)
/*
Msg 102, Level 15, State 1, Line XXXXX
Incorrect syntax near '0xd835'.
*/
-- D835 is the first character in the surrogate pair D835 DFDC that makes up U+1D7DC
TUY NHIÊN # 2 , thậm chí không tìm kiếm cơ sở dữ liệu Unicode có thể dễ dàng như vậy. Hai tìm kiếm này tạo ra một danh sách các ký tự hợp lệ cho các phân loại đó và các ký tự đó là từ Unicode 3.2, NHƯNG các định nghĩa về các phân loại khác nhau thay đổi trên các phiên bản của Tiêu chuẩn Unicode. Có nghĩa là, định nghĩa của "ID_Start" trong Unicode v 10.0 (những gì tìm kiếm đó đang sử dụng ngày hôm nay, 2018-03-26) không phải là những gì trong Unicode v 3.2. Vì vậy, tìm kiếm trực tuyến không thể cung cấp một danh sách chính xác. Nhưng bạn có thể lấy các tệp dữ liệu Unicode 3.2 và lấy danh sách các ký tự "ID_Start" và "ID_Continue" từ đó để so sánh với những gì SQL Server thực sự sử dụng. Và tôi đã thực hiện điều này và xác nhận một kết hợp chính xác với các quy tắc tôi đã nêu ở trên trong "TUY NHIÊN # 1".
Hai bài viết sau đây chi tiết các bước cần thực hiện để tìm danh sách chính xác các ký tự, bao gồm các liên kết đến tập lệnh nhập:
- Uni-Code: Tìm kiếm danh sách các ký tự hợp lệ cho mã định danh thông thường T-SQL, Phần 1
- Uni-Code: Tìm kiếm danh sách các ký tự hợp lệ cho mã định danh thông thường T-SQL, Phần 2
Cuối cùng, đối với bất kỳ ai chỉ muốn xem danh sách và không quan tâm đến những gì đã mất để khám phá và xác minh nó, bạn có thể tìm thấy ở đây:
Hoàn thành danh sách đầy đủ các ký tự định danh T-SQL hợp lệ
(vui lòng cho trang tải một chút thời gian; đó là 3,5 MB và gần 47 nghìn dòng)
Về các ký tự ASCII "hợp lệ", chẳng hạn như /
và -
không hoạt động: vấn đề không liên quan đến việc các ký tự đó có được xác định trong bộ ký tự ASCII hay không. Để có giá trị, nhân vật phải có một trong hai ID_Start
hoặc ID_Continue
tài sản, hoặc là một trong số ít những nhân vật tùy chỉnh ghi nhận riêng biệt. Có khá nhiều ký tự ASCII "hợp lệ" (62 trong tổng số 128 ký tự - chủ yếu là dấu chấm câu và ký tự điều khiển) không hợp lệ trong Mã định danh "Thông thường".
Về các ký tự bổ sung: mặc dù chúng chắc chắn có thể được sử dụng trong các định danh phân cách (và tài liệu dường như không được nêu rõ), nếu đúng là chúng không thể được sử dụng trong các định danh thông thường, rất có thể là do chúng không được hỗ trợ đầy đủ trong các chức năng tích hợp trước Bộ sưu tập nhận biết ký tự bổ sung đã được giới thiệu trong SQL Server 2012 (chúng được coi là hai ký tự "không xác định" riêng lẻ), thậm chí chúng không thể được phân biệt với nhau trong các Bộ sưu tập không nhị phân trước 100- Collations cấp (được giới thiệu trong SQL Server 2008).
Về ASCII: Mã hóa 8 bit không được sử dụng ở đây vì tất cả các mã định danh là Unicode / NVARCHAR
/ UTF-16 LE. Câu lệnh SELECT ASCII('ツ');
trả về giá trị 63
là "?" (thử SELECT CHAR(63);
:) vì ký tự đó, ngay cả khi có tiền tố chữ "N", chắc chắn không có trong Mã Trang 1252. Tuy nhiên, ký tự đó nằm trong Trang Mã Hàn Quốc và nó tạo ra kết quả chính xác, ngay cả khi không có "N "Tiền tố, trong Cơ sở dữ liệu có Đối chiếu mặc định của Hàn Quốc:
SELECT UNICODE('ツ'); -- 12484
Về chữ cái đầu tiên ảnh hưởng đến kết quả: điều này là không thể vì chữ cái đầu tiên cho các biến và tham số cục bộ luôn luôn @
. Chữ cái đầu tiên mà chúng ta có thể kiểm soát các tên này thực sự là ký tự thứ 2 của tên.
Về lý do tại sao tên biến cục bộ, tên tham số và GOTO
nhãn không thể được phân định: Tôi nghi ngờ điều này là do các mục này là một phần của chính ngôn ngữ và không phải là thứ sẽ tìm đường vào bảng hệ thống dưới dạng dữ liệu.