Tanımlayıcılar her zaman Unicode / ' NVARCHAR
dır, bu nedenle teknik olarak Unicode adı olmayan hiçbir şey oluşturamazsınız 🙃.
Burada yaşadığınız sorun tamamen kullanılan karakter (ler) in sınıflamasına bağlıdır. Düzenli (yani sınırlandırılmamış) tanımlayıcılar için kurallar şunlardır:
- İlk harf şöyle olmalı:
- Unicode Standard 3.2 tarafından tanımlandığı şekilde bir mektup.
- alt çizgi (_), (@) işaretinde veya sayı işaretinde (#)
- Sonraki harfler olabilir:
- Unicode Standard 3.2'de tanımlanan harfleri.
- Temel Latince veya diğer ulusal komut dosyalarından ondalık sayılar.
- alt çizgi (_), (@) işareti, sayı işareti (#) veya dolar işareti ($)
- Gömülü boşluklara veya özel karakterlere izin verilmez.
- Ek karakterlere izin verilmez.
Bu bağlamda önemli olan tek kuralları kalınca yazdım. "İlk harf" kurallarının burada geçerli olmama nedeni, tüm yerel değişken ve parametrelerdeki ilk harfin her zaman "işaret" olduğudur @
.
Ve açık olmak gerekirse: "harf" olarak kabul edilen ve "ondalık basamak" olarak kabul edilen şey , her karakterin Unicode Karakter Veritabanında atandığı özelliklere dayanır . Unicode, her karaktere, is_uppercase, is_lowercase, is_digit, is_decimal, is_combining, vb. Gibi birçok özellik atar. Bu, ölümlülerin harfleri veya ondalık basamakları dikkate alacağı, ancak hangi karakterlerin bu özelliklere atandığı meselesi değildir. Bu özellikler genellikle Örneğin, vb "noktalama" konulu maç için Normal İfadeler kullanılan, \p{Lu}
(tüm diller / komut boyunca) herhangi büyük harf ile eşleşir ve \p{IsDingbats}
herhangi bir "Dingbat'ler" karakteriyle eşleşir.
Yani, yapma girişiminde:
DECLARE @¯\_(ツ)_/¯ INT;
sadece _
(alt çizgi veya "düşük çizgi") ve ツ
(Katakana Letter Tu U + 30C4) karakterleri bu kurallara uyar. Şimdi, içindeki tüm karakterler ¯\_(ツ)_/¯
sınırlandırılmış tanımlayıcılar için gayet iyi, ancak ne yazık ki değişken / parametre adları ve GOTO
etiketler sınırlandırılamıyor gibi görünüyor (imleç adları olabilir).
Bu nedenle, değişken / parametre adları için sınırlandırılamadıkları için, Unicode 3.2'den yalnızca "harfler" veya "ondalık basamak" olarak nitelendirilen karakterleri kullanmak zorunda kalırsınız (belgelere göre; test etmem gerekiyor) Sınıflamalar, Unicode'un daha yeni sürümleri için güncellendiyse, sınıflandırmalar sıralama ağırlıklarından farklı olarak ele alınırsa).
Ancak # 1 , işler olması gerektiği kadar düz değildir. Şimdi araştırmamı tamamlayabildim ve belirtilen tanımlamanın tamamen doğru olmadığını tespit ettim. Normal tanımlayıcılar için hangi karakterlerin geçerli olduğu (ve doğrulanabilir) tanımı şöyledir:
İlk karakter:
- Unicode 3.2'de "ID_Start" olarak sınıflandırılan herhangi bir şey olabilir ("Harfler" i içerir ancak "harf benzeri sayısal karakterler" de bulunur)
- Olabilir
_
(düşük hat / çizgi) veya _
(Tam Kısa düşük hat)
- Olabilir
@
, ancak yalnızca değişkenler / parametreler için
- Olabilir
#
, ancak eğer şemaya bağlı nesne, o zaman sadece Tablolar ve Saklı Prosedürler için (bu durumda nesnenin geçici olduğunu gösterirler)
Sonraki karakterler:
- Unicode 3.2'de "ID_Continue" ("ondalık" sayılar, aynı zamanda "boşluk bırakma ve boşluk bırakmayan birleştirme işaretleri" ve "noktalama işaretlerini bağlama") olarak sınıflandırılan herhangi bir şey olabilir
- Olabilir
@
, #
veya$
- Unicode 3.2'de format kontrol karakterleri olarak sınıflandırılmış 26 karakterden herhangi biri olabilir
(eğlenceli gerçek: "ID_Start" ve "ID_Continue" içindeki "ID", "Tanımlayıcı" anlamına gelir. Hayal edin ;-)
"Unicode Utilities: UnicodeSet" 'e göre:
Geçerli başlangıç karakterleri
[: Yaş = 3.2:] & [: ID_Start = Evet:]
-- 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'.
*/
Geçerli devam karakterleri
[: Yaş = 3.2:] & [: ID_Continue = Evet:]
-- 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
NASIL # 2 , Unicode veritabanında arama yapmak bile bu kadar kolay olmayabilir. Bu iki arama, bu kategorizasyonlar için geçerli bir karakter listesi oluşturur ve bu karakterler Unicode 3.2'dendir, ANCAK Unicode Standard sürümleri arasında değişik kategorizasyon değişikliklerinin tanımlarıdır. Anlam (yani arama bugün hangisini kullandığına, 2018/03/26) Unicode v 10.0'da "ID_Start" tanımıdır değil Unicode v 3.2 içinde ne. Dolayısıyla, çevrimiçi arama kesin bir liste sağlayamaz. Ancak Unicode 3.2 veri dosyalarını ve SQL Server'ın gerçekte kullandıklarını karşılaştırmak için oradaki "ID_Start" ve "ID_Continue" karakterlerinin listesini alabilirsiniz. Ve bunu yaptım ve yukarıda "HOWEVER # 1" de belirtilen kurallara tam uyumu onayladım.
Aşağıdaki iki blog yazısı, içe aktarma komut dosyalarına bağlantılar da dahil olmak üzere tam karakter listesini bulmak için atılan adımları ayrıntılandırır:
- Uni-Code: T-SQL Düzenli Tanımlayıcıları İçin Geçerli Karakterlerin Gerçek Listesini Aramak, Bölüm 1
- Uni-Code: T-SQL Düzenli Tanımlayıcıları İçin Geçerli Karakterlerin Doğru Listesi İçin Arama, 2. Bölüm
Son olarak, sadece listeyi görmek isteyen ve onu keşfetmek ve doğrulamak için neyle uğraştığını düşünmeyen herkes için, burada bulabilirsiniz:
Tamamen Geçerli T-SQL Tanıtıcı Karakterlerin Listesi
(lütfen sayfaya yüklenmesi için bir dakika verin; 3.5 MB ve neredeyse 47k satır)
"Geçerli" olarak /
ve -
çalışmayan ASCII karakterleriyle ilgili olarak : sorunun ASCII karakter kümesinde karakterlerin de tanımlanıp tanımlanmadığı ile ilgisi yoktur. Geçerli olması için, karakterin ya da özelliğe sahip olması ya ID_Start
da ID_Continue
ayrı ayrı not edilen birkaç özel karakterden biri olması gerekir. "Normal" Tanımlayıcılarda geçerli olmayan birkaç "geçerli" ASCII karakteri (toplamda 128 noktalama (çoğunlukla noktalama ve kontrol karakteri) olmak üzere 62) vardır.
Tamamlayıcı Karakterlere İlişkin: Sınırlı tanımlayıcılarda kesinlikle kullanılabilirler (ve belgeler aksi belirtilmiş gibi görünmüyorsa da), normal tanımlayıcılarda kullanılamayacakları doğruysa, büyük olasılıkla tam olarak desteklenmemeleri nedeniyle Ek Karakter Aware Harmanlamalardan önceki yerleşik işlevlerde SQL Server 2012'de tanıtıldı (iki ayrı "bilinmeyen" karakter olarak kabul edilirler), hatta 100- den önceki ikili Harmanlamalarda birbirlerinden farklılaştırılamazlar. düzey Harmanlamalar (SQL Server 2008'de tanıtıldı).
ASCII ile ilgili olarak: 8 bit kodlamalar burada kullanılmamaktadır, çünkü tüm tanımlayıcılar Unicode / NVARCHAR
/ UTF-16 LE'dir. SELECT ASCII('ツ');
İfade 63
, "?" Olan bir değer döndürür. (deneyin SELECT CHAR(63);
:) bu karakter, büyük harf "N" ile önceden eklenmiş olsa bile, kesinlikle Kod Sayfası 1252'de değildir. Ancak, bu karakter Kore Dili Kod Sayfasındadır ve "N'siz bile" doğru sonucu üretir. "önek, Korece varsayılan Harmanlama içeren bir Veritabanında:
SELECT UNICODE('ツ'); -- 12484
Sonucu etkileyen ilk harf ile ilgili: yerel değişkenler ve parametreler için ilk harf her zaman olduğu için bu mümkün değildir @
. Bu isimler için kontrol edebileceğimiz ilk harf aslında ismin 2. karakteridir.
Yerel değişken adlarının, parametre adlarının ve GOTO
etiketlerin neden sınırlandırılamadığına ilişkin olarak: Bunun, bu öğelerin dilin bir parçası olması ve sistem tablosuna veri olarak girecek bir şey olmaması nedeniyle olduğundan şüpheleniyorum.