Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как исправить кодировку?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Добрый день. Есть проблемка, никак не соображу, как исправить.

Через BULK INSERT залили данные в таблицу. В текстовом файле кодировка была WIN1251. Но в параметрах BULK INSERT это учтено не было по ошибке. Т.е. залилось неправильно, посколько по умолчанию CODEPAGE = 'OEM'. Вопрос: как вернуть нормальную кодировку символов?
17 авг 09, 12:39    [7545795]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Похоже кодировка утеряна навсегда... Строка: "МАВЛИХАНОВ" превратилась в "¦LTTL-L=+T".

Самое фиговое, что первичный ключ записи после заливки меняется на текущее IDENTITY. Т.е. залить во временную таблицу и обновить значения полей не получится. :(
17 авг 09, 14:27    [7546522]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
vino
Member

Откуда:
Сообщений: 1191
Senya_L, работать update на перекодирование данных. OEM->ANSI 1251...
Если жалко времени:
1) если первичная заливка, то TRUNCATE и повтори с правильной кодировкой
2) иначе узнай количество плохих записей, удали их, обнови IDENTITY, теперь повтори с правильной кодировкой
17 авг 09, 16:26    [7547490]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
vino
Senya_L, работать update на перекодирование данных. OEM->ANSI 1251...
Если жалко времени:
1) если первичная заливка, то TRUNCATE и повтори с правильной кодировкой
2) иначе узнай количество плохих записей, удали их, обнови IDENTITY, теперь повтори с правильной кодировкой
ВОзможно я ошибаюсь, но похоже, что преобразование получилось необратимым:
автор
Строка: "МАВЛИХАНОВ" превратилась в "¦LTTL-L=+T"
Разные буквы "В" и "Л" превратились в "T" латинскую, что вообще странно. Как не ASCII-символы превратились в ASCII? Сейчас пробую удалить записи с помощью. Записи с кракозябрами пробую отфильтровать запросом
		SELECT
			[idPerson]
		FROM [Persons]
		WHERE NOT (
			[Surname] LIKE '%е%'
			OR [Surname] LIKE '%ю%'
			OR [Surname] LIKE '%у%'
			OR [Surname] LIKE '%ы%'
			OR [Surname] LIKE '%а%'
			OR [Surname] LIKE '%о%'
			OR [Surname] LIKE '%э%'
			OR [Surname] LIKE '%я%'
			OR [Surname] LIKE '%и%'
			OR [Surname] LIKE '%ю%'
		)
В расчете на то, что в фамилиях обязательно будет присутствовать хоть одна гласная буква. :)
17 авг 09, 16:36    [7547581]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
И в поля с какими типами данных заливалось?
17 авг 09, 16:39    [7547594]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
pkarklin
И в поля с какими типами данных заливалось?

CREATE TABLE [dbo].[Persons](
	...
	[Surname] [varchar](63) NOT NULL,
	[Name] [varchar](31) NOT NULL,
	[Secname] [varchar](31) NOT NULL
	...
)
Заливка непервичная. Связей немного, но я еще не очень хорошо ориентируюсь в структуре БД.
17 авг 09, 16:44    [7547629]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Не дописал пост и нажал Ctrl+Enter.
Связи я все отловил, запрос составил. Вот только меня критерий отыскания неверно залитых данных смущает.
17 авг 09, 16:46    [7547637]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
Senya_L
Заливка непервичная.


Т.е. данные уже заливались неоднократно и успешно?
17 авг 09, 16:50    [7547674]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
pkarklin
Senya_L
Заливка непервичная.


Т.е. данные уже заливались неоднократно и успешно?
Да. Заливались успешно, но потом была допущена ошибка в ХП. Для BULK INSERT'а не была указана кодовая страница. Потом запрос был исправлен и данные опять заливались правильно.
17 авг 09, 16:53    [7547690]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Кстати, вот такая получается таблица преобразования, если забыть заливать из файла с кодировкой WIN1251, а сервер будет думать, что там cp866
АБВГДЕЁЖЗИйКЛМНОПРСТУФХЦЧШЬЩЪЭЮЯ
L+T+-+覦Lщ¦T¦=+¦¦TTLL-г++---¦¦-
Вобщем-то с буквой "Ё" записей нет. Надеюсь... :(
17 авг 09, 16:56    [7547713]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
vino
Member

Откуда:
Сообщений: 1191
Senya_L
Кстати, вот такая получается таблица преобразования, если забыть заливать из файла с кодировкой WIN1251, а сервер будет думать, что там cp866
АБВГДЕЁЖЗИйКЛМНОПРСТУФХЦЧШЬЩЪЭЮЯ
L+T+-+覦Lщ¦T¦=+¦¦TTLL-г++---¦¦-
Вобщем-то с буквой "Ё" записей нет. Надеюсь... :(

так тут еще и г встречается...
Ясно, значит перекодировка...
Раз это разовая ошибка, лучше всего сначала найти по вашему критерию значения минимума и максимума ключа плохого диапазона, проверить этот диапазон для уверенности на отсутствие нормальных записей, а уже потом разовое обновление сделать c фильтром только по ключу.
17 авг 09, 18:06    [7548183]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
vino
Member

Откуда:
Сообщений: 1191
Senya_L, только заметил, что перекодировка какая-то неоднозначная, например
АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя
__'_":р┼╪_%_<_____''""--_T_>____ Ўў_¤_с│ЁcЄ<┐-RЇабвгдежзийклмноп
Лучше, все-таки узнать минимум и максимум ключа плохого диапазона и определить соответствие с нормальной загрузкой исходных данных во вспомогательную таблицу
17 авг 09, 18:14    [7548215]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
vino
Member

Откуда:
Сообщений: 1191
Senya_L, вот нашел таблицу преобразования, вроде все нормально, та только вместо строки нужно читать бинари, а потом конвертить по такой таблице
А = 80
Б = 81
В = 82
Г = 83
Д = 84
Е = 85
Ё = f0
Ж = 86
З = 87
И = 88
Й = 89
К = 8a
Л = 8b
М = 8c
Н = 8d
О = 8e
П = 8f
Р = 90
С = 91
Т = 92
У = 93
Ф = 94
Х = 95
Ц = 96
Ч = 97
Ш = 98
Щ = 99
Ъ = 9a
Ы = 9b
Ь = 9c
Э = 9d
Ю = 9e
Я = 9f
а = a0
б = a1
в = a2
г = a3
д = a4
е = a5
ё = f1
ж = a6
з = a7
и = a8
й = a9
к = aa
л = ab
м = ac
н = ad
о = ae
п = af
р = e0
с = e1
т = e2
у = e3
ф = e4
х = e5
ц = e6
ч = e7
ш = e8
щ = e9
ъ = ea
ы = eb
ь = ec
э = ed
ю = ee
я = ef
17 авг 09, 18:28    [7548256]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
vino
Senya_L, вот нашел таблицу преобразования, вроде все нормально, та только вместо строки нужно читать бинари, а потом конвертить по такой таблице
Спасибо, завтра попробую. Я уже хотел просто удалить все записи проблемные, да вот только придется еще поискать, из каких архивов заново заливку провести. Но предложенное решение выглядит гораздо симпатичнее. Еще раз благодарю.
17 авг 09, 22:39    [7548856]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
vino,

Не все нормально. Тестовый пример.
USE [Test]
GO

CREATE TABLE ttt(
	data VARCHAR(64)
)
GO
Создаем файл e:\test.txt, содержащий
АБВГДЕЁЖЗИйКЛМНОПРСТУФХЦЧШЬЩЪЭЮЯ
Выполняем
USE [Test]
GO

BULK INSERT ttt FROM 'E:\test.txt'
GO

SELECT data, CAST(SUBSTRING(data, 1, 1) AS VARBINARY(64)) FROM ttt
GO
Видим, что у символа "А" код 0x4C, что совсем не 0x80. Или я что-то не так делаю?
18 авг 09, 09:49    [7549651]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
vino
Member

Откуда:
Сообщений: 1191
То что выдает твой (чуть подправленный) пример, и используй для перекодировки. Я, конечно, ошибся, так как у тебя именно испорченная WIN1251 кодировка.
USE [Test]
GO
CREATE TABLE ttt(
	data VARCHAR(132)
)
GO
Создаем файл e:\test.txt, содержащий
АБВГДЕЁЖЗИйКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя
Выполняем
USE [Test]
GO

BULK INSERT ttt FROM 'E:\test.txt'
GO

SELECT data, CAST(data AS VARBINARY(132)) FROM ttt
GO
Результат выложишь?
18 авг 09, 10:40    [7549889]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
vino
Member

Откуда:
Сообщений: 1191
Только исправь в test.txt строку:
АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя
18 авг 09, 10:45    [7549908]     Ответить | Цитировать Сообщить модератору
 Re: Как исправить кодировку?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
vino
Я, конечно, ошибся, так как у тебя именно испорченная WIN1251 кодировка.
Я бы даже сказал так: текст к кодировке 1251 перекодированный как если бы он был в 866.
vino
То что выдает твой (чуть подправленный) пример, и используй для перекодировки.
Я так понимаю предлагаешь самому установить таблицу перекодировки? Есть проблема. Результат выкладываю
USE [Test]
GO

BULK INSERT ttt FROM 'E:\test.txt'
GO

SELECT data, CAST(data AS VARBINARY(132)) FROM ttt
GO
L+T+-+覦Lг¦T¦=+¦¦TTLL-г++----¦¦-рстуфх¬цчшщъыьэюяЁёЄєЇїЎў°•·v№¤¦ 	0x4C2B542B2D2BE8A6A64CE3A654A63D2BA6A654544C4C2DE32B2B2D2D2D2DA6A62DF0F1F2F3F4F5ACF6F7F8F9FAFBFCFDFEFFA8B8AABAAFBFA1A2B095B776B9A4A6A0
Плохие новости: есть повторы по байтам. :( Т.е. обратное преобразование невозможно.

ЗЫ. Сдается мне хлопчики в MS малость нахалтурили с преобразованием кодировок. Ну не может после перекодировки символ попасть с кодовой страницы в ASCII-набор. Ну никак.
18 авг 09, 12:10    [7550557]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить