照合順序をSQL_Latin1_General_CP1_CI_AS
として設定したMSSQLデータベースのVARCHAR
列にこの文字 '●'を挿入する必要があります(または、少なくとも私のモックアップPython + Windows MSSQLドライバーが完了した可能性があります。これをクライアントから挿入しようとしましたが、?
として挿入されます。
Python=でチェックされる16進値は\xe2\x97\x8f
で、これはバイナリ226、151、143です。
照合 spec は、226が定義されているが、143と151は未定義であることを示しています。私のベストは226を挿入することでしょうか?
私がこの演習を行っているのは、私たちのアプリが以前にこのキャラクターをDBに挿入していたためです。この時点では、それがどのように行われたかはわかりませんが、Python Windows MSSQLドライバーを使用したアプリを実行し、DBチームがそれを修正するためのスクリプトを作成しました。 「?」.
今、私はこのシナリオを再現して、なぜ「?」に置き換えられるのかを尋ねようとしています。アプリでは空として置き換えているためです。私のアプリには既にこの問題の修正が含まれているため(127より大きいものは削除されます)、これをバックエンドから直接モックして、「?」に置き換えられることを証明しようとしています。これは実際には私の主張であり、更新クエリで「COLLATE」と表示されているために行われたと思います。
UPDATE pr_response
SET nur_respon =
REPLACE (nur_respon,
SUBSTRING(nur_respon, PATINDEX('%[^ !-~]%' COLLATE Latin1_General_BIN, nur_respon), 1),
'')
WHERE PATINDEX('%[^ !-~]%' COLLATE Latin1_General_BIN, nur_respon) > 0
これは、非ASCIIデータ> 127を削除するための素晴らしいスクリプトですか?誰かがこのクエリを分かりやすい英語で説明できますか?
この文字「●」を
VARCHAR
列に挿入する必要があります...照合をSQL_Latin1_General_CP1_CI_AS
に設定します...この演習を行っている理由は、アプリがこの文字をDBに挿入していたためですついさっき。
いいえ、アプリは[SQL_]Latin1_General...
照合順序を使用してVARCHAR
列にこの文字( Black Circle U + 25CF )を挿入していませんでした。 Latin1_General Collationsは Code Page 1252 を使用しますが、そのような文字はなく、「最適な」マッピングが存在しないように見えるため、類似したものに変換することもできません。
その文字は、次のクエリが示すように、韓国語と日本語の照合で使用されるものなど、一部のコードページに存在します(どちらも2バイト文字セットであるため、VARBINARY
への変換では2バイトが表示されますひとつの):
SELECT CONVERT(VARCHAR(10), N'●' COLLATE Korean_100_CI_AS),
CONVERT(VARBINARY(10), CONVERT(VARCHAR(10), N'●' COLLATE Korean_100_CI_AS));
-- ● 0xA1DC
SELECT CONVERT(VARCHAR(10), N'●' COLLATE Japanese_XJIS_100_CI_AS),
CONVERT(VARBINARY(10), CONVERT(VARCHAR(10), N'●' COLLATE Japanese_XJIS_100_CI_AS));
-- ● 0x819C
SELECT CONVERT(VARCHAR(10), N'●' COLLATE Latin1_General_100_CI_AS),
CONVERT(VARBINARY(10), CONVERT(VARCHAR(10), N'●' COLLATE Latin1_General_100_CI_AS));
-- ? 0x3F
ただし、アプリが '•'( Bullet U + 2022 )を挿入していた可能性があります。 「弾丸」文字はコードページ1252(12月149または16進0x95)で使用できます。
私たちのDBチームはそれを修正するスクリプトを書いて、どうやら "?"に置き換えられました。
さて、「●」を「?」に置き換えてそれを修正するようには聞こえません;-)。
今、私はこのシナリオを再現して、なぜ「?」に置き換えられるのかを尋ねようとしています。アプリでは空として置き換えているためです。私のアプリにはすでにこの問題の修正が含まれているため(127を超えるものはすべて削除されます)
専門性に関係なく、両方のステートメントが同時にtrueになることはあり得ないことはかなり明白です。「?」で置き換えることはできません。 およびは、SQL Serverにアクセスする前に削除されます。明らかにアプリのコードはこれを修正ししないであり、しない127を超える値を持つすべてを削除します。「?」に変換されますSQL Serverでは、その文字がまだ挿入されているため、コードページ1252には存在しません。
更新クエリで「COLLATE」と表示されているので、完了したと思います。
いいえ、COLLATE
キーワードを介してバイナリ照合を強制しても、この文字は「?」に変更されません。列の照合順序(SQL_Latin1_General_CP1_CI_AS
)と明示的な照合順序(Latin1_General_BIN
)はどちらもコードページ1252を使用するため、これにより文字が変更されることはありません。
「●」文字は「?」に置き換えられますVARCHAR
列に挿入されているためです。また、クエスチョンマークとして挿入されると、クリーンアップするものは何もありません。また、クエスチョンマークを、意図されたクエスチョンマークではなく、他の何かに由来するものとして識別する方法はありません。
これは、非ASCIIデータ> 127を削除するための素晴らしいスクリプトですか?誰かがこのクエリを分かりやすい英語で説明できますか?
このクエリは、ASCII値が127を超える文字(つまり、PATINDEX
が行うこと)をすべて検出し、そのような文字(つまり、SUBSTRING
は)、次に列内のその文字のすべての出現を空の文字列で置き換えます(これはREPLACE
が行うことです)。クエリはUPDATE
を実行しません。 ASCII 127を超える値を持つ文字が見つかりました。
このクエリは、一度に1つの文字に対してのみ機能します。したがって、列にASCII 127を超える値があり、同じでないASCII値を持つ2つ以上の文字がある場合、スクリプトは複数実行する必要があります。回。
その変換は途中で行われているため、このクエリはこの特定のケース(つまり、「●」を「?」で置き換える)では役に立ちません。このクエリは、ASCII値が128の文字のみを処理します-255、まだ "●"はこれらの文字の1つではありません。そもそもこの列には決してないからです。