web-dev-qa-db-ja.com

SQLスクリプトがANSIエンコーディングで実行されていることを確認するにはどうすればよいですか?

たぶんこれは愚かな質問なのか、間違った方法で質問しているのでしょう。

スクリプト(数千行)がANSIエンコーディングで実行されていることをどのように確認できますか?

Notepad ++(SQLとOracleのプログラマコードを同時に使用)を使用してスクリプトを作成し、それをEncode in ANSIで保存するとします。

enter image description here

OK。次に、スクリプト内に_Â_文字を入れます。クライアントがこのスクリプトを別のエンコーディングを使用しているツールにコピーしただけの場合(実際、理由はわかりませんが、一部のユーザーはこれを行っており、エラーを検出しないことは確かです)、これは_Â_に変換されます: enter image description here ですが、スクリプトには数千行あるため、クライアント側でこれに気付く人はいません。

ユーザーにはこれが表示されないことがわかっています。スクリプト全体を読んで問題がないことを確認することはありません。これを行うために支払われたDBAでさえ、これを実行しません(私はDBAであり、常にすべてのスクリプトを常に読んでいます)。

それで、ユーザーが_F5_を押すと、すべてのスクリプトがこれらの奇妙な文字なしで、送信したのと同じようにANSIでエンコードされていることをどのように確認できますか?これは、データベースの正しい照合でのみ達成できますか?

私はcase when asci character = the ascii(character) then ok else ERRORを使用してスクリプトの最初の行で次のようなことを考えていました(テストにasciiを使用):

_Select CHAR(ASCII('ã')) As Teste_CHAR, CHAR(227) as Teste_CHAR_ASCII
_

ソロモン、これはクエリです:

_Select *,
Case
        When Teste_CHAR=Teste_CHAR_ASCII
        Then 'OK'
        Else 'Erro'
END as STATUS_TESTE,
Case
       When Teste_CHAR=Teste_CHAR_ASCII
       Then 'Everything is OK'
       Else 'Script will not run. your encode is different from ours'
END as Mensagem_TESTE
 from (
Select CHAR(ASCII('ã')) As Teste_CHAR, CHAR(227) as Teste_CHAR_ASCII
) A
_
3
Racer SQL

では、ユーザーがF5キーを押すと、送信したのと同じように、すべてのスクリプトがこれらの奇妙な文字なしでANSIでエンコードされていることをどのように確認できますか?

確かではありません。これは、テキストエンコーディング、特に非Unicodeエンコーディングの、残念ながら複雑な性質です。すべてが単なるバイトです。画面に表示されるのは、これらのバイトの単なる解釈です。あるエンコーディングは、同じバイトまたはバイトシーケンス(エンコーディングによって異なる)に対して、別のエンコーディングとは異なる「文字」を表示する可能性がありますが、技術的には、バイトはバイトであり、すべてのバイトが有効です。

_Â_の場合、差異がないため差異を検出できません。 Notepad ++では_xC2_のみが表示されます。これはその文字のバイト値ですが、それ自体は有効なUTF-8またはUTF-16/UCS-2バイトシーケンスではないため、Notepad ++はバイト自体。

さて、Unicodeエンコーディング(UTF-8、UTF-16、またはUTF-32)のいずれかと8ビットエンコーディングの間を行き来することは、8ビットコードページにない文字を見つけてそれと比較することで検出できます。 _?_/CHAR(63)、そしてそれらが一致する場合、Unicodeエンコーディングを使用していません。

ここでの欠点は、8ビットエンコーディングでは、それらがどのエンコーディング/コードページであるかを示す方法がないことです。あなたはただ知っている必要があります。ただし、Unicodeエンコーディングには、ファイルの先頭に数バイトを配置して、使用されているエンコーディングのタイプを示すオプションがあります。このバイトシーケンスはバイトオーダーマーク(BOM)と呼ばれ、正しいエンコーディングの場合、表示されません。

したがって、最善の策は、Unicodeエンコーディングの1つを使用し、バイトオーダーマーク(BOM)でファイルを保存することです。通常、BOMの有無にかかわらず、Unicodeエンコーディングで保存することを選択できるためです。 Notepad ++(私が使用しています)では、2つのUCS-2オプションはどちらもBOMのみですが、UTF-8を選択できます。スクリプトが現在ANSIを使用している場合は、Notepad ++のEncodingメニューでTF-8-BOMに変換を選択し、ファイルを保存します。次に、SSMSにコピーして貼り付けると、すべて問題なく動作します。そして、ほとんどのエディターでそのファイルを開くと、BOMが存在するため、UTF-8としてエンコードされていることが自動的に検出されます。

これは、データベースの正しい照合でのみ達成できますか?

これはSQL Serverとは関係ありません。これは、クライアントツールとそれが使用しているエンコーディングに関係しています。 SSMSはほぼ間違いなくUTF-16 LE(リトルエンディアン)を使用しています。これは、Windows/SQL Server/.NETが使用しているものだからです。


質問の最後に最近追加されたクエリについて:

_ã_の値は、ANSIエンコーディングでは_0xE3_ですが、UTF-8またはUTF-16では無効です。 Notepad ++では、エンコーディングをUTF-8に変更すると(「エンコード」、not「変換先」を使用)、_xE3_のみが表示されます。クエリのそのバージョンをSSMSにコピーして貼り付けると、そのバイトと次のバイト(最後の_'_に使用されるバイト)が加算され、それが__に変換されてクエリが中断されます。終了の見積もりがないため。 _ã_の後に2つのスペースを追加して、次のように修正することができます。

_CHAR(ASCII('ã  '))
_

ASCII関数は最初の文字の値のみを返し、追加の文字(2つのスペース)は無視されるため、エンコードが変更されていない場合でも期待どおりに機能します。

そのスクリプトがインポートまたはUTF-8に変更された場合、スクリプトはNotepad ++で次のように表示されます。

_CHAR(ASCII('xE3  '))
_

そして、その_xE3_は単一の「文字」になります。クエリのコピーと貼り付けそのバージョンをSSMSに貼り付けると、次のように表示されます。

_CHAR(ASCII('㠠'))
_

そしてそれを実行すると、望ましい「エラー」結果が生成されます。

HOWEVER、これはnot間違いのない/保証されたテストであることに注意してください。これは主に、スクリプトがUTF-8、UTF-16、または_ã_文字を含まない8ビットコードページとして誤って開かれたことを示しています。

このアプローチはnotを実行すると、スクリプトがANSIではないが_ã_文字を含み、他の文字を誤って解釈(つまり変更)する可能性がある8ビットエンコーディングとして開かれた場合、エラーを示します。 。

ANSIエンコーディングを保証する唯一の方法は、a)他の8ビットコードページで使用できない文字を見つけることですand b)UTF-8またはUTF-16では同じではありません。使用可能なすべてのコードページに対してすべてをチェックしたわけではありませんが、そのような文字は認識していません。

しかし、UTF-8としてファイルを開く人だけを扱う場合は、上記の調整を行うと、その状況でうまくいくはずです。

6
Solomon Rutzky