さて、識別子は常にUnicode / NVARCHAR
であるため、技術的にはUnicode名がないものは作成できません🙃。
あなたがここで抱えている問題は、使用されているキャラクターの分類によるものです。通常の(つまり、区切られていない)識別子のルールは次のとおりです。
- 最初の文字は:
- Unicode Standard 3.2で定義されている文字。
- アンダースコア(_)、アットマーク(@)、または番号記号(#)
- 後続の文字は次のとおりです。
- Unicode Standard 3.2で定義されている文字。
- ベーシックラテンまたはその他の国のスクリプトからの10進数
- アンダースコア(_)、アットマーク(@)、番号記号(#)、またはドル記号($)
- 埋め込みスペースまたは特殊文字は使用できません。
- 補助文字は使用できません。
この文脈で重要な唯一のルールを太字にしました。ここで「最初の文字」ルールが関係ないのは、すべてのローカル変数およびパラメーターの最初の文字が常に「アットマーク」であるため@
です。
そして、明確にするために、「文字」と見なされるものと「10進数字」と見なされるものは、Unicode文字データベースで各文字が割り当てられるプロパティに基づいています。Unicodeは、is_uppercase、is_lowercase、is_digit、is_decimal、is_combiningなど、多くのプロパティを各文字に割り当てます。これは、人間が文字や10進数字と見なすものではなく、どの文字にこれらのプロパティが割り当てられているかという問題ではありません。これらのプロパティは、「句読点」などに一致するために正規表現でよく使用されます。たとえば、\p{Lu}
すべての大文字(すべての言語/スクリプト)に\p{IsDingbats}
一致し、「Dingbats」文字に一致します。
だから、あなたの試みで:
DECLARE @¯\_(ツ)_/¯ INT;
のみ_
(アンダースコアまたは「低ライン」)およびツ
(カタカナ手紙火U + 30C4)文字は、それらの規則に適合します。現在、すべての文字は¯\_(ツ)_/¯
デリミタ付き識別子に適していますが、残念ながら変数/パラメータ名とGOTO
ラベルはデリミタ付きではないようです(ただし、カーソル名は区別できます)。
したがって、変数/パラメータ名については、それらを区切ることができないため、Unicode 3.2の時点で「文字」または「10進数」のいずれかとして修飾される文字のみを使用することに固執しています(まあ、ドキュメントによると、テストする必要があります分類はソートの重みとは異なる方法で処理されるため、ユニコードの新しいバージョンの分類が更新されている場合)。
しかし#1、物事は本来あるべきほど単純ではありません。私は今、研究を完了することができ、記載された定義が完全に正しいわけではないことがわかりました。通常の識別子に有効な文字の正確な(かつ検証可能な)定義は次のとおりです。
最初のキャラクター:
- Unicode 3.2で「ID_Start」として分類されたもの(「レター」だけでなく「文字のような数字」も含む)
- することができ
_
(低ライン/アンダースコア)または_
(全角低ライン)
- にすることができますが
@
、変数/パラメータのみ
- にすることができますが
#
、スキーマバインドオブジェクトの場合は、テーブルとストアドプロシージャのみ(この場合、オブジェクトが一時的であることを示します)
後続の文字:
- Unicode 3.2で「ID_Continue」(「10進数」の数字だけでなく、「間隔と非間隔の結合マーク」、および「句読点の接続」を含む)として分類されるものであれば何でもかまいません。
- することができ
@
、#
または$
- Unicode 3.2で形式制御文字として分類されている 26文字のいずれか
(楽しい事実:「ID_Start」と「ID_Continue」の「ID」は「Identifier」の略です。想像してみてください;-)
「Unicode Utilities:UnicodeSet」によると:
有効な開始文字
[:年齢= 3.2:]&[:ID_Start =はい:]
-- 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'.
*/
有効な継続文字
[:年齢= 3.2:]&[:ID_Continue =はい:]
-- 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
ただし#2、Unicodeデータベースを検索することすら簡単ではありません。これらの2つの検索は、これらの分類に有効な文字のリストを生成します。これらの文字はUnicode 3.2からのものですが、さまざまな分類の定義はUnicode標準のバージョンによって異なります。つまり、UnicodeのV 10.0で「ID_Start」の定義は(その検索は今日、2018年3月26日を使用しているもの)ではない、それはUnicodeのV 3.2であったもの。そのため、オンライン検索では正確なリストを提供できません。ただし、Unicode 3.2データファイルを取得し、そこから「ID_Start」および「ID_Continue」文字のリストを取得して、SQL Serverが実際に使用しているものと比較できます。そして、私はこれを実行し、上記の「HOWEVER#1」で述べたルールに完全に一致することを確認しました。
次の2つのブログ投稿では、インポートスクリプトへのリンクなど、文字の正確なリストを見つけるための手順を詳しく説明しています。
- ユニコード:T-SQL正規識別子の有効な文字の真のリストの検索、パート1
- ユニコード:T-SQL正規識別子の有効な文字の真のリストの検索、パート2
最後に、リストを見たいだけで、それを発見して検証するのに何が必要かを気にしない人は、ここでそれを見つけることができます:
有効なT-SQL識別子文字の完全なリスト
(ページをロードする時間を与えてください。3.5MBおよびほぼ47k行です)
「有効」のASCII文字、などについて/
や-
、動作しない:問題は、文字はまた、ASCII文字セットに定義されているかどうかとは関係ありません。有効にするために、キャラクターはID_Start
またはID_Continue
プロパティのいずれかを持っているか、別途記載されている数少ないカスタムキャラクターのいずれかでなければなりません。「通常の」識別子では有効ではない「有効な」ASCII文字がかなりあります(合計128個のうち62個—ほとんどが句読点と制御文字)。
補助文字について:区切られた識別子で使用できることは確かですが(そして、ドキュメントはそれ以外の場合は記載されていないように見えます)、通常の識別子で使用できないことが本当なら、それはおそらく完全にサポートされていないためです補足文字認識照合より前の組み込み関数では、SQL Server 2012に導入されました(2つの個別の「不明な」文字として扱われます)。100-より前の非バイナリ照合では、それらを区別することさえできません。レベルの照合(SQL Server 2008で導入)。
ASCIIに関して:すべての識別子はUnicode / NVARCHAR
/ UTF-16 LE であるため、8ビットエンコーディングはここでは使用されていません。ステートメントは、「?」SELECT ASCII('ツ');
で63
ある値を返します (試してみてくださいSELECT CHAR(63);
)大文字の "N"が前に付いていても、その文字は確かにコードページ1252にはありません。ただし、その文字は韓国語のコードページにあり、 "N 「韓国語のデフォルト照合を使用したデータベースのプレフィックス:
SELECT UNICODE('ツ'); -- 12484
結果に影響する最初の文字に関して:ローカル変数とパラメータの最初の文字は常にであるため、これは不可能@
です。これらの名前を制御する最初の文字は、実際には名前の2番目の文字です。
ローカル変数名、パラメーター名、およびGOTO
ラベルを区切ることができない理由について:これは、これらの項目が言語自体の一部であり、データとしてシステムテーブルに入る方法ではないためと思われます。