5

私は、Microsoft SQL Server 2005 データベースを MySQL 5.6 に移行する任務を負っています (これらはどちらもローカルで実行されているデータベース サーバーです)。

-MSSQLソースデータベースにはlatin1照合があります(ISO 8859-1文字セットは正しいですか?)が、char/varcharフィールドがないため(文字列フィールドはnvarchar/ncharです)、このデータはすべてUCS-2文字を使用する必要があります設定。

-MySQL ターゲット データベースは文字セット UTF-8 を必要とします

MySQL ワークベンチの最新バージョンでデータベース移行ツールキットを使用することにしました。最初は問題なく動作し、すべてが期待どおりに移行されました。しかし、MSSQL データベースで UCS-2 サロゲート ペア文字に遭遇したとき、私は完全につまずきました。

移行ツールキットの copytable プログラムは、「wstring の文字セット変換中にエラーが発生しました: エラーはありません」という有用なエラー メッセージを提供しませんでした。また、問題の原因となったデータに関するフィールド/行情報も提供せず、100 行のチャンク内で失敗しました。そのため、最後に挿入が成功した後に 100 行を検索したところ、nvarchar フィールドの 1 つにある 2 つの UCS-2 文字が問題の原因であることがわかりました。これらは、UCS-2 文字セットのサロゲート ペアとしてリストされています。それらは具体的には文字 DBC0 と DC83 でした (これは、フィールドのバイナリ データを見て、バイト ペア (リトル エンディアン) と正常に移行されたデータを比較することでわかりました)。

このサロゲート ペアが MSSQL データベースから削除されると、行は MySQL に正常に移行されました。

問題は次のとおりです。

これらの文字をテスト MSSQL テーブル (この chartest テーブルはさまざまなテスト文字列と nvarchar フィールドです) で検索して、置換スクリプトを準備し、奇妙な結果を得ようとしました...何か間違ったことをしているに違いありません。

探している

SELECT * FROM chartest WHERE text LIKE NCHAR(0xdc83)

任意のサロゲート ペア文字 (DC83 を使用するかどうかにかかわらず) を返しますが、明らかに、それがそのフィールド内の唯一の文字 (またはペアの一部) である場合に限ります。とにかくこれらのインスタンスを削除したいので、これは大したことではありません (このようなデータを削除するのは好きではありませんが、余裕があると思います)。

探している

SELECT * FROM chartest WHERE text LIKE '%' + (NCHAR(0xdc83))+ '%'

すべての行を返します!DC83文字はもちろん、フィールドにUnicode文字が存在するかどうかに関係なく。これらの文字を見つけて置き換えるより良い方法はありますか? または、他に試してみるべきことがありますか?

また、対象のデータベース、テーブル、およびフィールドの文字セットを UCS-2 に設定しようとしましたが、違いはないようです。

また、この移行ではライブ データ (最大 50 GB のデータベース!) を使用していますが、それをフィードするサイトの 1 つがオフラインになっているため、これに対するソリューションには迅速な実行時間が必要です...

提案をいただければ幸いです。抜けている情報があれば教えてください。

4

4 に答える 4

4

このエラーが発生しましたが、問題の原因を発見しました。私は見つけるのに苦労したので、これは誰かに役立つかもしれません.

MSSQL から MySQL にデータを移行しています。移行されるコンテンツは、Sitecore CMS の html コンテンツです (ターゲット CMS は Drupal です)。

データベースを変換してInstagram-embedsを含むレコードをヒットすると、このエラーが発生することがわかりました。Instagram-embeds は、埋め込まれた投稿データが埋め込みコードにコピーされるという方法で機能します (非同期でロードされる代わりに、など - 画像でさえ base64-css として含まれます...)。最近では、画像の説明に多くの絵文字を入れる傾向があります (絵文字キーボード付きの iPhone を使用)。絵文字は 4 バイトでエンコードされた文字で表されますが、MySQLutf8では 3 バイトでエンコードされた Unicode 文字しか使用できません。

実行時の最初のエラーwbcopytables.exe(MySQL Workbench で Migration Wizard を GUI を使用せずに実行する方法) は、

wstring の文字セット変換中のエラー: エラーなし

しかし、MySQL Workbench を最新バージョン ( 5.somethingから6.xに) にアップグレードすると、エラーがもう少し説明的になり、テーブルと列 (ああ、行ではありません) がヒントになります:

エラー: テーブル [MyDatabase].[dbo].[MyTable] (列 MyColumn) で UCS-2 文字列を UTF-8 に正常に変換できませんでした。元の文字列: ...

utf8mb4とにかく -絵文字を許可する解決策*かもしれません* 。詳細はこちらをご覧ください

しかし、たとえば私の Drupal の場合、これを行うのは悪い考えのようです。

そのため、最終的な解決策は、移行スクリプトでこれらの文字を単純に削除することでした。問題のサイトのユーザーのためにこれらを保持しても意味がありません。とにかく、それらは Web ページ上で長方形として表示されているからです。SQL Server では正規表現を検索して置換することはできないため、DAL と c# .NET を使用してデータを処理しました。ここでヘルプを見つけました ( Jon Skeetさんに感謝します) -正規表現があることがわかりました- UTF-16 のサロゲート ペアの半分に一致するパターン。以下を参照してください (必要に応じて別の言語でパターンを使用してください)。

var noUcs2SurrogatePairsString = Regex.Replace(stringWithUcs2SurrogatePairs, @"\p{Cs}", string.Empty);
于 2015-01-20T13:48:09.387 に答える
2

私は今日、非常によく似た問題を抱えていました.空の文字列が原因であることがわかりました.NULLまたはデータがないことを表す値に置き換えられ、移行は正常に機能しました.

于 2016-05-18T07:55:20.463 に答える
0

この問題は解決されました。ここでは、ユーザー の Remus Rusanu の提案を使用して、これらのサロゲート ペア文字を使用して行を検索し、次のような厄介な文字を除外するために使用することにしました。CHARINDEXSUBSTRING

UPDATE test
SET a = SUBSTRING(a,  1,   (CHARINDEX(0x83dc, CAST(a AS VARBINARY(8000)))+1)/2 - 1) -- string before the unwanted character
+ SUBSTRING(a, (CHARINDEX(0x83dc, CAST(a AS VARBINARY(8000)))+1)/2 +1, LEN(a) ) -- string after the unwanted character
WHERE CHARINDEX(0x83dc, CAST(a AS VARBINARY(8000))) % 2 = 1 -- only odd numbered charindexes (to signify match at beginning of byte pair character)
于 2013-03-26T08:55:10.297 に答える