Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
abrashka Member Откуда: Сообщений: 517 |
День добрый! Имею некоторую проблему с кодировками, но это в другой теме... В таблицах сохранились данные, содержащие знак вопроса внутри ромба(Unicode block). Хочу найти все проблемые строки, но не знаю как поставить условие, т.е. select ascii(substring('этот хитрый знак',1,1)); select unicode(substring('этот хитрый знак',1,1)); выдают 63, но это обычный знак вопроса на сколько я понимаю, а мне не нужны строки, которые содержат знак вопроса, мне нужны только содержащие знак вопроса в ромбе. Т.е. мне если мне нужны строки, куда закрался этот хитрый знак, то что мне написать в Like? select * from MyTable where Col_1 like .... Спасибо! |
22 окт 14, 19:27 [16745248] Ответить | Цитировать Сообщить модератору |
msLex Member Откуда: Сообщений: 8725 |
N'этот хитрый знак'
|
22 окт 14, 19:33 [16745265] Ответить | Цитировать Сообщить модератору |
abrashka Member Откуда: Сообщений: 517 |
msLex, если имелось в виду: select * from MyTable where Col_1 like N'%этот хитрый знак%' то получаю всю таблицу |
22 окт 14, 19:36 [16745281] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Значит этот хитрый знак есть во всей таблице |
||
22 окт 14, 21:31 [16745663] Ответить | Цитировать Сообщить модератору |
a_voronin Member Откуда: Москва Сообщений: 4807 |
abrashka, U+FFFD � replacement character used to replace an unknown or unrepresentable character А вы уверены, что вам нужен этот хитрый символ, а не нечто, что он заменил. Отконвертируйте входные строки в varbinary и поcмотрите, что там стоит. |
23 окт 14, 12:46 [16747721] Ответить | Цитировать Сообщить модератору |
o-o
Guest |
select unicode(substring('�',1,1)) as u1, unicode(substring(N'�',1,1)) as u2; --- u1 u2 63 65533 (у меня там не вопросик набит, a 'этот хитрый знак' (see attachment) прилагаю занимательную картинку, объясняющую ВСЕ :) конечно же, выполняю все в базе с некириллическим коллэйшеном К сообщению приложен файл. Размер - 19Kb |
||
23 окт 14, 15:51 [16749402] Ответить | Цитировать Сообщить модератору |
abrashka Member Откуда: Сообщений: 517 |
a_voronin, Мне не так важно, что этот знак заменяет, мне важно найти все строки, в которых существует проблема, т.е. в которых находится этот знак, а дальше уже будем чинить. Вот я и думаю, как выбрать только проблемные строки... Что значит "Отконвертируйте входные строки в varbinary"? Типа: ![]() Как это может мне помочь? Мне нужны только строки с этими знаками вопроса, вот и не знаю, что поставить в WHERE: select * from MyTable where ... |
23 окт 14, 16:49 [16749850] Ответить | Цитировать Сообщить модератору |
a_voronin Member Откуда: Москва Сообщений: 4807 |
CAST(ваше поле AS VARBINARY(MAX)) Посмотрите, что там за коды (в числах) и от этих кодов отталкивайтесь. Может вам подойти с другой стороны: составить список допустимых символов и найти все строки, где есть символы кроме допустимых. |
||
23 окт 14, 16:54 [16749886] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Это должно показать вам код символа, который вы называете странным. Или натолкнуть на мысль искать любой НЕразрешенный символ NOT LIKE '%[^<здесь список разрешенных символов>]%' |
||
23 окт 14, 16:58 [16749911] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47051 |
|
||||
23 окт 14, 17:01 [16749928] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Возможно. Я про принцип поиска. |
||||
23 окт 14, 17:04 [16749952] Ответить | Цитировать Сообщить модератору |
abrashka Member Откуда: Сообщений: 517 |
Glory, Спасибо, буду искать не разрешенные о-о, Спасибо! Но в моем случае проблема немного другая: ![]() Первый селект выдает все значения, а от второго и третьего я ожидаю получить только строки содержащие "хитрый знак", т.е. 1,2,3,6,7 Но в первом случае не получаю данных вообще, а во втором получаю строки 4,5,8, которые точне но не содержут ничего особенного. |
23 окт 14, 17:08 [16749972] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Вы что не понимаете, что этим "хитрым знаком" при отображении могут заменяться множество разных символов ? |
||
23 окт 14, 17:10 [16749989] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47051 |
abrashka, Col_1 какого типа? |
23 окт 14, 17:12 [16750004] Ответить | Цитировать Сообщить модератору |
abrashka Member Откуда: Сообщений: 517 |
Glory, Уже понимаю:) iap, Col_1 nvarchar |
23 окт 14, 17:29 [16750133] Ответить | Цитировать Сообщить модератору |
o-o
Guest |
мой пост показывал: 1. почему у вас код был 63, хотя код "вопроса в ромбе" совсем не 63 :) 2. в последнем запросе видно, что ромбы ему мерещатся всюду 3. остальное показывало, что если ИСХОДНЫЕ ДАННЫЕ неправильно занести (передать неюникод хоть бы и в юникодное поле, в базе с не тем коллэйшеном), то в таблицу лягут вопросики и потом уже всегда будут выдаваться любым лайком, если сравнивать с неюникодом, к-ый тоже в вопросики превратится, если в базе латинский коллэйшен ...но что у вас-то в таблице не вопросики, а латинские aaa, bbb, мне в голову не пришло. сейчас подумаю снова! |
||
23 окт 14, 17:48 [16750252] Ответить | Цитировать Сообщить модератору |
msLex Member Откуда: Сообщений: 8725 |
Это действительно какой-то "странный" символ ни like '%...%' ни like '%[^...]%' его как-будто не видят. if object_id('tempdb..#t') is not null drop table #t create table #t (c nvarchar(100)) declare @strange_symbol nchar(1) = cast(0xFFDF as nchar(100)) insert #t (c) select cast(N'1' as nvarchar(100)) union all select cast(N'2' as nvarchar(100)) union all select cast(N'1' as nvarchar(100)) + cast(@strange_symbol as nvarchar(100)) union all select cast(N'2' as nvarchar(100)) + cast(@strange_symbol as nvarchar(100)) select * from #t where c like N'%' + cast(@strange_symbol as nvarchar(100)) + N'%' select * from #t where c like N'%[^12]%' select * from #t where c like N'%[^1]%' select * from #t where c like N'%[^2]%' |
23 окт 14, 17:51 [16750270] Ответить | Цитировать Сообщить модератору |
msLex Member Откуда: Сообщений: 8725 |
Решение - использовать BIN коллейшнif object_id('tempdb..#t') is not null drop table #t create table #t (c nvarchar(100)) declare @strange_symbol nchar(1) = cast(0xFFDF as nchar(100)) insert #t (c) select cast(N'1' as nvarchar(100)) union all select cast(N'2' as nvarchar(100)) union all select cast(N'1' as nvarchar(100)) + cast(@strange_symbol as nvarchar(100)) + cast(N'1' as nvarchar(100)) union all select cast(N'2' as nvarchar(100)) + cast(@strange_symbol as nvarchar(100)) + cast(N'2' as nvarchar(100)) select * from #t where c collate Latin1_General_BIN like N'%' + cast(@strange_symbol as nvarchar(100)) + N'%' collate Latin1_General_BIN |
23 окт 14, 18:08 [16750361] Ответить | Цитировать Сообщить модератору |
abrashka Member Откуда: Сообщений: 517 |
o-o, Пока нашел такое решение, конвертировать стринг в varchar и искать по двум знакам вопроса. В реальной жизни(в моей системе, речь идет о типах документов) врядли будет тип с двумя знаками вопроса подряд. А вот "проблемное" слово таким образом отображается знаками вопроса, тогда можно получить все проблемные строки, хотя конечно не 100%: ![]() |
23 окт 14, 18:12 [16750384] Ответить | Цитировать Сообщить модератору |
o-o
Guest |
msLex, можно еще короче. тем более, что вынимая из таблицы символ, collate ему уже как мертвому припарка К сообщению приложен файл. Размер - 11Kb |
23 окт 14, 18:17 [16750408] Ответить | Цитировать Сообщить модератору |
abrashka Member Откуда: Сообщений: 517 |
msLex, Спасибо за помощь, но в моем случае это не работает, я упростил задачу для наглядности, на самом деле правильная строка выгледит так:
Формат данных: код английского языка;английское название;код русского языка;русское название T.e. по ошибке строку 92 зашли данные с неверной кодировкой, вместо слова "Событие" в базе появились знаки вопроса(хитрые знаки), так мне нужно получить только данные с "хитрыми знаками"(92). Если я запускаю Ваш скрипт, то не получаю данные вообще. |
|||||||||
23 окт 14, 18:28 [16750461] Ответить | Цитировать Сообщить модератору |
soljo_ua Member Откуда: Киев Сообщений: 369 |
ASCII - возвращает значение знака вопроса можно перебором искать, но долго можно кастонуть поле в varchar и искать по '%?%' IF OBJECT_ID('tempdb..#t') IS NOT NULL DROP TABLE #t CREATE TABLE #t ( c NVARCHAR(100) ) DECLARE @strange_symbol NCHAR(1) = CAST(0xFFDF AS NCHAR(100)) INSERT #t ( c ) SELECT CAST(N'1' AS NVARCHAR(100)) UNION ALL SELECT CAST(N'2' AS NVARCHAR(100)) UNION ALL SELECT CAST(N'1' AS NVARCHAR(100)) + CAST(@strange_symbol AS NVARCHAR(100)) + CAST(N'1' AS NVARCHAR(100)) UNION ALL SELECT CAST(N'2' AS NVARCHAR(100)) + CAST(@strange_symbol AS NVARCHAR(100)) + CAST(N'2' AS NVARCHAR(100)) SELECT c,CAST(c AS VARCHAR(100)) FROM #t WHERE CAST(c AS VARCHAR(100)) LIKE '%?%' |
23 окт 14, 18:28 [16750463] Ответить | Цитировать Сообщить модератору |
msLex Member Откуда: Сообщений: 8725 |
Когда происходит сравнение строк с разными коллейтами, сервер (при возможности) сам приводит обе строки к одному коллейту Так что в вашем случае это конверт все равно есть, только он не явный. В вашем примере конечным коллейтом выбран BIN, но я не поручусь, что нет него коллейта, в котором "странный" символ игнорируется, но при этом он более "приоритетен" чем BIN. Я бы не стал на это закладываться и явно приводил обе строки к одному коллейту в моем примере тоже ошибка, я привел только последний %, правильно так select * from #t where c collate Latin1_General_BIN like (N'%' + cast(@strange_symbol as nvarchar(100)) + N'%') collate Latin1_General_BIN |
||
23 окт 14, 18:29 [16750466] Ответить | Цитировать Сообщить модератору |
o-o
Guest |
да все работает y msLex, просто ромбу надо насилько BIN коллэйшен прописать: К сообщению приложен файл. Размер - 9Kb |
||
23 окт 14, 18:33 [16750489] Ответить | Цитировать Сообщить модератору |
msLex Member Откуда: Сообщений: 8725 |
Значит у вас другие хитрые символы, и, как вам уже предлагали, нужно идти от допустимых символов, но делать это в BIN коллейте. Учтите что диапазоны ([a-z]) в bin коллейте могут покрывать другие символы нежели в обычном cyrillic коллейте. Возможно самый надежный способ - это явно перечислить все допустимые символы (с учетом регистра) |
|||||||||||
23 окт 14, 18:35 [16750497] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
Все форумы / Microsoft SQL Server | ![]() |