2013-03-22 8 views
5

Zostałem zlecony migracji bazy danych Microsoft SQL Server 2005 do MySQL 5.6 (są to oba serwery bazy danych uruchomione lokalnie) i naprawdę doceniłbym jakąś pomoc.Migracja MSSQL na MySQL - problemy z kodowaniem znaków z parami zastępczymi UCS-2, jak mogę je usunąć z bazy danych MSSQL?

-Zebrane źródło danych MSSQL ma układ łaciński1 (czyli ma ustawiony znak ISO 8859-1?), Ale nie ma żadnych pól char/varchar (dowolne pole łańcuchowe to nvarchar/nchar), więc wszystkie te dane powinny być używane Zestaw znaków UCS-2.

-MySQL docelowej bazy danych chce zestaw znaków UTF-8

postanowiłem użyć zestawu narzędzi migracji bazy danych w najnowszej wersji MySQL Workbench. na początku działało dobrze i migrowało wszystko zgodnie z oczekiwaniami. Ale byłem całkowicie potknięty po napotkaniu znaków zastępczych UCS-2 w bazie danych MSSQL.

Program do kopiowania pakietu narzędzi do migracji nie zawiera bardzo przydatnego komunikatu o błędzie: "Błąd podczas konwersji zestawu znaków w wątku: Brak błędu". Nie dostarczono również żadnych informacji o polu/wierszu danych powodujących problemy i nie powiedzie się w porcjach o rozmiarze 100 wierszy. Po przeszukiwaniu 100 wierszy po ostatnim pomyślnym wstawieniu stwierdziłem, że problem spowodowany był dwoma znakami UCS-2 w jednym z pól nvarchar. Są one wymienione jako pary zastępcze w zestawie znaków UCS-2. Były to w szczególności postacie DBC0 i DC83 (dostałem to, patrząc na dane binarne dla pola i porównując pary bajtów (little endian) z danymi, które były migrowane pomyślnie).

Gdy ta zastępcza para została usunięta z bazy danych MSSQL, wiersz został pomyślnie przeniesiony do MySQL.

Oto problem:

Próbowałem szukać tych znaków w tabeli testowej MSSQL (tabela ta chartest jest tylko różne ciągi testów pola nvarchar) przygotowanie skryptu zastępczą i wciąż otrzymuję dziwne wyniki. .. Muszę robić coś niepoprawnie.

wyszukiwania

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

Wrócimy żadnego zastępczego charakteru pary (czy nie używa DC83), ale oczywiście tylko wtedy, gdy jest to jedyna postać (lub część tej pary) w tej dziedzinie. Nie jest to wielka sprawa, ponieważ i tak chciałbym usunąć dowolną ich instancję (nie lubię usuwać takich danych, ale wydaje mi się, że możemy sobie na to pozwolić).

wyszukiwania

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

Wrócimy każdy wiersz! Niezależnie od tego, czy ma on nawet znak Unicode obecny w polu, nie mówiąc już o postaci DC83. Czy istnieje lepszy sposób na znalezienie i zastąpienie tych postaci? Lub coś innego, co powinienem spróbować?

Próbowałem także ustawić docelowy zestaw danych, tabela i zestaw znaków pola na UCS-2, ale wydaje się, że nie robi różnicy.

Należy również wspomnieć, że migracja ta wykorzystuje dane żywe (~ bazy 50GB!) Podczas jednego z obiektów, który karmi go w tryb offline więc wszelkie rozwiązania tej potrzeby na szybki czas pracy ...

Byłbym wdzięczny za wszelkie sugestie bardzo! Daj mi znać, jeśli są jakieś informacje, które pominąłem.

Odpowiedz

0

Ten problem został rozwiązany. Kiedyś użytkownikowi Remus Rusanu's sugestię here na znalezienie wiersze z tych zastępczych postaci pary za pomocą CHARINDEX i postanowiliśmy skorzystać SUBSTRING wykluczyć kłopotliwych znaków tak:

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) 
+0

To się ze mną dzieje, mam tabelkę o nazwie tblSenderRzever - otrzymuję ten sam błąd na tblSenderRzever. W tej tabeli, gdy uruchamiam to zapytanie TYLKO w nvarcharze, dotyczy to 0 wierszy. Czy jest jakiś pomysł, co się dzieje? – maor10

+0

@ user1005978 Celowałem w konkretne postacie, które powodowały u mnie problem. Znalazłem tylko te znaki, przeszukując określoną partię 100 wierszy, w których oprogramowanie migracji się nie powiodło. Czy jesteś w stanie zidentyfikować, które wiersze/pola mają ten problem? Następnie możesz zidentyfikować potencjalnie kłopotliwe postacie (w moim przypadku była to para zastępcza UCS-2 DBC0 i DC83). – JonM

4

miałem ten błąd, a teraz odkryłem źródło problemu. Trudno mi było się dowiedzieć, więc może to przyda się komuś, choć zdaję sobie sprawę, że mój problem i obejście problemu mogą nie być trafne w kwestii oryginalnych problemów z opcjami.

Przeprowadzam migrację danych z MSSQL do MySQL, a migrowana zawartość to treść HTML z Sitecore CMS (docelowy CMS to Drupal, btw).

Znalazłem, że pojawia się ten błąd podczas konwertowania bazy danych i naciśnięcia rekordów, które zawierają Instagram-embeds. Utwory Instagrama działają w taki sposób, że osadzone dane pocztowe są kopiowane do kodu osadzającego (zamiast być ładowanym asynchronicznie., Et.c. - nawet obraz jest zawarty jako base64-css ...), a młodzi ludzie obecnie mają tendencję do umieszczania wielu emoji w ich opisach obrazków (używając ich iPhone'ów z klawiaturą Emoji). Emotikony są reprezentowane przez czterobajtowe zakodowane znaki, ale MySQL utf8 zezwala tylko na 3-bajtowe kodowane znaki Unicode.

Mój początkowy błąd z systemem wbcopytables.exe (który jest non-GUI sposób robienia Kreatora migracji w MySQL Workbench) był

Error during charset conversion of wstring: No error

ale uaktualniania MySQL Workbench do najnowszej wersji (od 5.something do 6.x) sprawia, że ​​błąd nieco bardziej opisowego, dając do zrozumienia, stół i kolumnę (niestety, nie rząd):

ERROR: Could not successfully convert UCS-2 string to UTF-8 in table [MyDatabase].[dbo].[MyTable] (column MyColumn). Original string: ...

Zresztą - a * rozwiązanie mogłoby być wykorzystanie * utf8mb4, które pozwoliłyby na emoji. Czytaj więcej here.

Ale wygląda na to, że jest to a bad idea, aby zrobić to w np. moja sprawa z Drupalem.

Więc - rozwiązaniem, które udało mi się rozwiązać, było po prostu usunięcie tych znaków z mojego skryptu migracyjnego. Nie ma sensu utrzymywanie ich dla użytkowników danej strony, ponieważ i tak są one wyświetlane w postaci prostokątów na stronie. Ponieważ nie można wyszukiwać i zastępować wyrażeniem regularnym w SQL Server, przetworzyłem dane za pomocą DAL i C# .NET, i znalazłem pomoc here (dziękuję ton, Jon Skeet) - okazuje się, że istnieje wzór regex za dopasowanie połowy zastępczej pary w UTF-16. Zobacz poniżej (iw razie potrzeby użyj wzorca w innym języku).

var noUcs2SurrogatePairsString = Regex.Replace(stringWithUcs2SurrogatePairs, @"\p{Cs}", string.Empty); 
2

I rozwiązać właśnie edycji „Dane import script.cmd”, w którym czytamy kolumny „Jak NVARCHAR” poprzez zastąpienie tych z „VARCHAR” tylko.

Uwaga: Moje kolumny tabeli były już typu VARCHAR, więc ... z jakiegoś głupiego powodu skrypt migracji nieprawidłowo rzucił go na typ UNICODE (NVARCHAR).

+1

To mi pomogło. Przechodziłem od VARCHAR do VARCHAR, a mimo to wypuściłem skryptowany CAST do NVARCHAR/NCHAR. Poprawiłem skrypt tak, jak wspomniałem i to rozwiązało mój problem. –

2

Miałem bardzo podobny problem już dziś i stwierdziłem, że było to spowodowane pustymi ciągami, zastąpiono je wartościami NULL lub wartością reprezentującą brak danych, a migracja działała bez zarzutu.